diff -r 75abdd7f2568 roundup/cgi/templating.py --- a/roundup/cgi/templating.py Thu Jul 30 17:16:32 2026 -0400 +++ b/roundup/cgi/templating.py Mon Aug 03 02:15:38 2026 +0000 @@ -3747,12 +3747,32 @@ # backwards-compatibility raise AttributeError(name) if name not in self.client.instance.templating_utils: + # allow use of localReplace in templates allowing tracker + # admin to override using extensions mechanism - issue2559030. + if name == "localReplace": + return self.__localReplace raise AttributeError(name) return self.client.instance.templating_utils[name] def keywords_expressions(self, request): return render_keywords_expression_editor(request) + @staticmethod + def __localReplace(message): + """Default no-op for localReplace. + + Override with real definition in extensions. + + This allows templates to ship with localReplace(....) + and have an: + + instance.registerUtil('localReplace', local_replace) + + define localReplace with the same call signature (i.e. no self) + in the extension definition. + """ + return message + def html_calendar(self, request): """Generate a HTML calendar.