django-sitetree icon indicating copy to clipboard operation
django-sitetree copied to clipboard

Incorporate one dynamic tree into another

Open xlevus opened this issue 4 years ago • 2 comments

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.

xlevus avatar Jun 08 '20 14:06 xlevus

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:

xlevus avatar Jun 08 '20 14:06 xlevus

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.

idlesign avatar Jun 09 '20 05:06 idlesign