mirror of
https://github.com/discourse/discourse.git
synced 2024-12-22 20:43:50 +08:00
216845e4c7
Template overrides have been advised against for a long time, and are increasingly hard to maintain as Discourse's development accelerates. This commit officially deprecates this customization method, which will be removed in the not-too-distant future (likely in the first half of 2025).
121 lines
3.2 KiB
JavaScript
121 lines
3.2 KiB
JavaScript
import deprecated from "./deprecated";
|
|
|
|
const pluginRegex = /^discourse\/plugins\/([^\/]+)\/(.*)$/;
|
|
const themeRegex = /^discourse\/theme-([^\/]+)\/(.*)$/;
|
|
|
|
function appendToCache(cache, key, value) {
|
|
let cachedValue = cache.get(key);
|
|
cachedValue ??= [];
|
|
cachedValue.push(value);
|
|
cache.set(key, cachedValue);
|
|
}
|
|
|
|
const NAMESPACES = ["discourse/", "admin/"];
|
|
|
|
function isInRecognisedNamespace(moduleName) {
|
|
for (const ns of NAMESPACES) {
|
|
if (moduleName.startsWith(ns)) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
function isTemplate(moduleName) {
|
|
return moduleName.includes("/templates/");
|
|
}
|
|
|
|
/**
|
|
* This class provides takes set of core/plugin/theme modules, finds the template modules,
|
|
* and makes an efficient lookup table for the resolver to use. It takes care of sourcing
|
|
* component/route templates from themes/plugins, and also handles template overrides.
|
|
*/
|
|
class DiscourseTemplateMap {
|
|
coreTemplates = new Map();
|
|
pluginTemplates = new Map();
|
|
themeTemplates = new Map();
|
|
prioritizedCaches = [
|
|
this.themeTemplates,
|
|
this.pluginTemplates,
|
|
this.coreTemplates,
|
|
];
|
|
|
|
/**
|
|
* Reset the TemplateMap to use the supplied module names. It is expected that the list
|
|
* will be generated using `Object.keys(requirejs.entries)`.
|
|
*/
|
|
setModuleNames(moduleNames) {
|
|
this.coreTemplates.clear();
|
|
this.pluginTemplates.clear();
|
|
this.themeTemplates.clear();
|
|
for (const moduleName of moduleNames) {
|
|
if (isInRecognisedNamespace(moduleName) && isTemplate(moduleName)) {
|
|
this.#add(moduleName);
|
|
}
|
|
}
|
|
}
|
|
|
|
#add(originalPath) {
|
|
let path = originalPath;
|
|
|
|
let pluginMatch, themeMatch, cache;
|
|
if ((pluginMatch = path.match(pluginRegex))) {
|
|
path = pluginMatch[2];
|
|
cache = this.pluginTemplates;
|
|
} else if ((themeMatch = path.match(themeRegex))) {
|
|
path = themeMatch[2];
|
|
cache = this.themeTemplates;
|
|
} else {
|
|
cache = this.coreTemplates;
|
|
}
|
|
|
|
path = path.replace(/^discourse\/templates\//, "");
|
|
|
|
appendToCache(cache, path, originalPath);
|
|
}
|
|
|
|
/**
|
|
* Resolve a template name to a module name, taking into account
|
|
* theme/plugin namespaces and overrides.
|
|
*/
|
|
resolve(name) {
|
|
const [themeMatch, pluginMatch, coreMatch] = this.prioritizedCaches.map(
|
|
(cache) => {
|
|
const val = cache.get(name);
|
|
if (val) {
|
|
return val[val.length - 1];
|
|
}
|
|
}
|
|
);
|
|
|
|
if ((themeMatch || pluginMatch) && coreMatch) {
|
|
deprecated(
|
|
`[${
|
|
themeMatch || pluginMatch
|
|
}] Overriding templates is deprecated, and will soon be disabled. Use plugin outlets, CSS, or other customization APIs instead.`,
|
|
{
|
|
id: "discourse.resolver-template-overrides",
|
|
url: "https://meta.discourse.org/t/247487",
|
|
}
|
|
);
|
|
}
|
|
|
|
return themeMatch || pluginMatch || coreMatch;
|
|
}
|
|
|
|
/**
|
|
* List all available template keys, after theme/plugin namespaces have
|
|
* been stripped.
|
|
*/
|
|
keys() {
|
|
const uniqueKeys = new Set([
|
|
...this.coreTemplates.keys(),
|
|
...this.pluginTemplates.keys(),
|
|
...this.themeTemplates.keys(),
|
|
]);
|
|
return [...uniqueKeys];
|
|
}
|
|
}
|
|
|
|
export default new DiscourseTemplateMap();
|