django-sitetree
django-sitetree copied to clipboard
Incorporate one dynamic tree into another
Files:
# myproj/settings.py
INSTALLED_APPS = [
'sitetree',
'base',
'keywords',
]
# myproj/urls.py
...
from sitetree.sitetreeapp import register_dynamic_trees, compose_dynamic_tree, SiteTree
from sitetree.utils import tree, item
base = compose_dynamic_tree(
"base")
keywords = compose_dynamic_tree(
"keywords", target_tree_alias="sidenav", parent_tree_item_alias="sidenav_1"
)
register_dynamic_trees(
base, keywords, reset_cache=True,
)
# keywords/sitetrees.py
from sitetree.utils import tree, item
sitetrees = [
tree(
"keywords",
items=[
item(
"Keywords",
"index",
children=[item("Manage Keywords", "keywords-list",)],
)
],
),
]
# base/sitetrees.py
sitetrees = [
tree("sidenav", items=[item("Sidenav 1", "index", alias="sidenav_1")],),
]
# templates/example.html
{% load sitetree %}
{% sitetree_tree from "sidenav" %}
I would expect the following to be rendered by sitetree_tree
:
- Sidenav 1
+- Keywords
+- Manage Keywords
Except, I get:
- Sidenav 1
If I run python manage.py sitetree_resync_apps
and then disable SITETREE_DYNAMIC_ONLY
it works fine.
I suspect the issue lies somewhere around here in sitetree/sitetreeapp.py
:
535 if not sitetree:
536 if DYNAMIC_ONLY:
537 sitetree = []
538
539 else:
540 sitetree = (
541 MODEL_TREE_ITEM_CLASS.objects.
542 select_related('parent', 'tree').
543 prefetch_related('access_permissions__content_type').
544 filter(tree__alias__exact=alias).
545 order_by('parent__sort_order', 'sort_order'))
546
547 -> sitetree = self.attach_dynamic_tree_items(alias, sitetree)
548 set_cache_entry('sitetrees', alias, sitetree)
549 caching_required = True
453 items = []
454 if not src_tree_items: # THIS IS AN EMPTY ARRAY WHEN `DYNAMIC_ONLY` IS TRUE.
455 if _IDX_ORPHAN_TREES in trees and tree_alias in trees[_IDX_ORPHAN_TREES]:
456 for tree in trees[_IDX_ORPHAN_TREES][tree_alias]:
458 else: # THIS ATTACHMENT BRANCH NEVER GETS RUN
459
460 # TODO Seems to be underoptimized %)
461
462 # Tree item attachment by alias.
463 for static_item in list(src_tree_items):
464 items.append(static_item)
465 if not static_item.alias:
466 continue
467
468 idx = _IDX_TPL % (tree_alias, static_item.alias)
469 if idx not in trees:
The purpose of SITETREE_DYNAMIC_ONLY
as documented here is to prevent reading static trees from DB entirely.
sitetree_resync_apps
is to make your trees static.
Attaching tree items was initialy implemented to allow attachment of dynamic nodes to static. In your case, if I understand correctly, you want to attach items from one dynamic tree into another. I'm afraid this case is not covered now. Maybe we could implement that, but it'll probably require registering trees using some definite sequence (first parents, then children).
If you have any ideas of how could this be solved in a backward-compatible, robust and convenient way, you're welcome.