Issue 2550930
Created on 2016-10-26 11:17 by ber, last changed 2026-08-11 03:56 by rouilj.
| msg5916 |
Author: [hidden] (ber) |
Date: 2016-10-26 11:17 |
|
Because the classic template is most complete,
I suggest to add support for the local_replace.py
extension to it.
Here is a patch doing so.
(And I am also adding an example for a more advanced local_replace.py)
|
| msg6306 |
Author: [hidden] (ThomasAH) |
Date: 2018-12-11 14:17 |
|
The patches add functionality to the extensions directory and
additionally makes this extension required by using it in the html
templates.
If it is required by the classic template, I'd rather see it integrated
into the core.
Additionally the configuration for the extension will happen in the
extension itself. Having a configuration mechanism similar to
schema.py or interfaces.py (in the tracker root directory, in the case
of interfaces.py even an optional file) might be preferable.
|
| msg6307 |
Author: [hidden] (ThomasAH) |
Date: 2018-12-11 14:30 |
|
One additional thought: Adding it as a default extension might be OK, if
the extension code and the configuration code can be separated and the
extension provides a sane default when running without further
configuration.
|
| msg8481 |
Author: [hidden] (rouilj) |
Date: 2026-08-03 00:41 |
|
The way I am doing this is to:
add a @staticmethod called localReplace to templating.py::TemplatingUtils
this defined localReplace(message) and uses static method to keep the same calling
signature (i.e. without self).
In instance.py: change registerUtil(name, func) to see if the name being registered
already exists as an attribute on self.TemplatingUtils. If it does, use setattr to
replace self.TemplatingUtils.name with staticmethod(func).
If the attribute isn't defined, add it to self.templating_utils[name].
Patch attached.
I am a little uncertain about replacing the attribute. registerUtilMethod does the
replacement/overwrite because of the way it's written, but this may be wrong.
I am not sure why the original code is using self.templating_utils[] rather than
just setattr() on the TemplatingUtils class. Is it possible I could contaminate
another thread running against a different tracker (e.g. with wsgi or roundup-server
in thread mode)?
When I added the new definition to self.templating_utils[], the code was still calling the
@staticmethod on TemplatingUtils. If I could invert the resolution order so templating_utils[]
was checked first, then I wouldn't have to setattr on TemplatingUtils.
IIUC __getattr__ is called if __getattribute__ raises an AttributeError and __getattribute__
always looks in self.__dict__ for a match. So maybe I should redefine __getattribute__ to:
if name in self.client.instance.templating_utils:
return self.client.instance.templating_utils[name]
if name in self.__dict__:
return self.__dict__[name]
raise AttributeError(name)
Thoughts welcome.
|
| msg8482 |
Author: [hidden] (rouilj) |
Date: 2026-08-03 02:16 |
|
This is a second try to provide a default implementation of localReplace that can be
overridden using the extension method.
I define __localReplace(message) in TemplatingUtils.
In __getattr__ I look up the name in self.client.instance.templating_utils. If it is not
found, check to see if the name is 'localReplace'. If so, return self.__localReplace.
This allows a fallback for _localReplace so we can add it in the right places in the templates.
But it doesn't support overriding existing TemplatingUtils methods.
See: add_localReplace_to_all_templates2.diff
|
| msg8483 |
Author: [hidden] (rouilj) |
Date: 2026-08-03 03:05 |
|
Third way add __getattribute__() to TemplatingUtils. Look up name first in
self.client.instance.templating_utils. If not found look up as instance attribute.
This is a problem if internal names starting with '_' are allowed to be registered.
So registerUtil and registerUtilMethod prevent any name starting with underscore '_'.
I am still unsure if registerutilMethod by manipulating the class attributes could
leak changes into trackers running in other threads. If it does, I may have to figure
out how to create a templating_utils_method dict and call the functions in it like
a method would be called.
See: add_localReplace_to_all_templates.diff
|
| msg8489 |
Author: [hidden] (rouilj) |
Date: 2026-08-05 16:59 |
|
a patch on issue 2551421 will redo the registration methods.
It does away with __getattr__ by calling setattr on the TemplatingUtil object
instance for the tracker. This simplifies lookup.
The instance.registerUtil* methods block registering any util starting with
'_' or the name client. But all other methods on the TemplatingUtil object can
be replaced by registering them.
The instance registerUtil* methods check for duplicate names and give pointers
to the files/lines where the conflict happens.
|
| msg8490 |
Author: [hidden] (rouilj) |
Date: 2026-08-11 03:56 |
|
Done in changeset: 8747:551a9f8dcae1
There is now an example in customizing.txt.
The extended example attached to this ticket is similar to the default
ones
in the devel or responsive templates. They are now referenced in the
docs.
|
|
| Date |
User |
Action |
Args |
| 2026-08-11 03:56:42 | rouilj | set | status: new -> fixed type: rfe resolution: remind -> fixed messages:
+ msg8490 |
| 2026-08-05 16:59:45 | rouilj | set | messages:
+ msg8489 |
| 2026-08-03 03:05:07 | rouilj | set | files:
+ add_localReplace_to_all_templates3-__getattribute__.diff messages:
+ msg8483 |
| 2026-08-03 02:16:33 | rouilj | set | files:
+ add_localReplace_to_all_templates2.diff messages:
+ msg8482 |
| 2026-08-03 00:41:29 | rouilj | set | resolution: remind |
| 2026-08-03 00:41:04 | rouilj | set | files:
+ add_localReplace_to_all_templates.diff nosy:
+ rouilj messages:
+ msg8481 |
| 2018-12-11 14:30:50 | ThomasAH | set | messages:
+ msg6307 |
| 2018-12-11 14:17:41 | ThomasAH | set | nosy:
+ ThomasAH messages:
+ msg6306 |
| 2016-10-26 11:19:40 | ber | set | files:
+ local_replace.py |
| 2016-10-26 11:18:15 | ber | set | components:
+ Web interface |
| 2016-10-26 11:17:58 | ber | set | versions:
+ devel |
| 2016-10-26 11:17:54 | ber | create | |
|