View Single Post
Old 10-07-2022, 11:58 AM   #3
chaley
Grand Sorcerer
chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.chaley ought to be getting tired of karma fortunes by now.
 
Posts: 12,476
Karma: 8025702
Join Date: Jan 2010
Location: Notts, England
Device: Kobo Libra 2
Quote:
Originally Posted by capink View Post
However, this brings up something I've thinking about for a while now; would it possible to add another mode called python mode to the template language. I don't know how easy to implement this would be. The idea is that it passes mi object were we can process it directly. It would be more handy than defining a template function in python — for every use once scenario — and calling it from other modes. Of-course, if the implementation involves more than just a simple pass-through, it would not be worth the effort.
Hmmm... interesting. I can see how to do it using the same syntax as function definition, something like this:
Code:
    pydef x(a, b, ...)
        python code goes here
        it returns some string
    fedyp #Yes, this is strange but consistent
The lines between pydef and fedyp must be indented correctly for python. I would convert leading tabs to 4 spaces to avoid problems where tabs and spaces are intermixed such as when using copy/paste.

A pydef() would generate a python class that like this, where "locals" is the formatter local variable dict.
Code:
class x(object):
    def do_it(mi, locals_dict, a, b, ...)
        python code goes here
        the code must return a string or None
This compiled class could be stored in a dict named something like python_functions.

A call would look like every other function call, with mi and the locals dict automagically added to the argument list. The actual call to x by the template processor would be something like
Code:
    python_functions['x'].do_it(mi, locals, a, b, c)
The biggest problem is avoiding recompiling the function every time the template is used. I think I can deal with the majority of cases by adding to the existing template cache mechanism used for composite columns and template searches. In the db, cache.py and search.py keep a copy of the parsed template, reusing it as required. I could add the python functions there.

The next biggest problem is the db isn't always accessible to the python code. It is available for any mi created by cache.py.get_metadata(). In some cases the mi is built by hand or from a json dict, such as the templates in save_to_disk. These templates will fail if the python code attempts to use the db (cache.py.someting()) because mi._proxy_metadata will be None. Template functions such as book_values() have the same problem so we might be able to ignore it.

I think the above would more useful if it integrated with the proposed dict_() functions. The python code could set or get values from the internal support dictionary passed as a parameter. Any dict_() call template code would operate on the same dict, permitting the two to interact.
chaley is offline   Reply With Quote