tetra-framework / tetra

Tetra - A full stack component framework for Django using Alpine.js
https://www.tetraframework.com
MIT License
540 stars 14 forks source link

resolve_component finds wrong app if extended base template is in another app #26

Closed nerdoc closed 3 months ago

nerdoc commented 1 year ago

https://github.com/samwillis/tetra/blob/3f8fd3586eddd836983ec73ddad5ecfa3707e785/tetra/component_register.py#L44

This line gets the template of the component. I suppose in most cases this is working, but here I have a component which is in the "homepage" app, and the template which uses the component extends a base template which is in the "core" app.

While debugging the tetra code, I found that context.render_context.template.origin.name is "core", and context.template.origin.name is (the correct) "homepage".

So I think that the *render_context" is not necessary - at least when I remove it, it works properly.

nerdoc commented 1 year ago

So the line should be:

template = context.template 

Please tell mi if I should make a PR. But as there are no tests, I can't test further. It works perfectly for me here.

nerdoc commented 3 months ago

Definitely tested again. Tetra seems to assume that the base template (in my case "html.html" that is in app A and that is extended in app B) contains the component. So if a component is defined in B's template:

{% extends "A/html.html" %}
{% block content %}
    {% @ foo / %}
{% endblock %}

It seems that Tetra finds the base template and uses that as the component's app_config. So, really, it finds A's foo component where it should find B's component. I can test that by declaring the Foo component in A and B apps with different content.

This is correctly resolved when instead of context.render_context.template just context.template is used. I triple-checked with all combinations, but this seems to be the fix.

nerdoc commented 3 months ago

The error is simple and has nothing to do with the finding algorithm. Just to write it down, if we don't find it later:

In https://github.com/tetra-framework/tetra/blob/d52f38436e44341615fc8c17194a1a1b26c0117b/tetra/component_register.py#L29, when a component module of any app cannot be imported, the import just is ignored and noone will ever know why the import fails. This is often done when importing modules dynamically for convenience, but hinders debugging. E.g. when the module imports another module that is not installed, it will be silently ignored, no cascaded ModuleNotFoundError will be raised. This is e.g. if the sourcetypes module is not installed in the demo run. All the demo components are just vanished, and no error message shows up.

I added a logging error when the ModuleNotFoundError exception is triggered. So at least on the server log output something is displayed as help.