tutorial template plugin how cmspluginbase cms recursion menu parent-child django-cms tree-structure

recursion - template - install django cms ubuntu



MenĂș desplegable de niveles mĂșltiples de Django CMS (1)

¡WOHO! ¡Finalmente lo hice!

base.html

<div class="navbar-collapse collapse"> <ul class="nav navbar-nav"> {% show_menu 0 100 100 100 "menu.html" %} </ul> </div>

menu.html:

{% for child in children %} <li class="child{% if child.selected %} selected{% endif %}{% if child.ancestor %} ancestor{% endif %}{% if child.sibling %} sibling{% endif %}{% if child.descendant %} descendant{% endif %}{% if child.children %} dropdown{% endif %}"> <a {% if child.children %}class="dropdown-toggle" data-toggle="dropdown"{% endif %} href="{{ child.attr.redirect_url|default:child.get_absolute_url }}"> <span>{{ child.get_menu_title }}</span>{% if child.children|length %}<span class="caret"></span>{% endif %} </a> {% if child.children %} <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu"> {% show_menu from_level to_level extra_inactive extra_active "dropdownmenu.html" "" "" child %} </ul> {% endif %} </li> {% if class and forloop.last and not forloop.parentloop %}{% endif %} {% endfor %}

y mi dropdownmenu.html: (Las cosas recursivas comienzan aquí)

{% load i18n menu_tags cache mptt_tags %} {% for child in children %} <li {% if child.children %}class="dropdown-submenu"{% else %} {% endif %}> <a tabindex="-1" href="{{ child.attr.redirect_url|default:child.get_absolute_url }}">{{ child.get_menu_title }}</a> {% if child.children %} <ul class="dropdown-menu"> {% show_menu from_level to_level extra_inactive extra_active "dropdownmenu.html" "" "" child %} </ul> {% endif %} </li> {% endfor %}

y lo más importante, menu.py:

class TopicsSubMenu(CMSAttachMenu): name = _("Wiki Sub-Menu") def get_nodes(self, request): nodes = [] categories = Category.objects.all() for c in categories: node = NavigationNode( mark_safe(c.name), c.get_absolute_url(), c.pk ) if c.parent: node.parent_id = c.parent_id nodes.append(node) topics = Topic.objects.all().exclude(category__isnull=True) for t in topics: node = NavigationNode( mark_safe(t.title), t.get_absolute_url(), t.pk, t.category.all()[0].id, parent_namespace="TopicsSubMenu" ) nodes.append(node) return nodes menu_pool.register_menu(TopicsSubMenu)

¡Y eso es!

Soy un poco nuevo en Django CMS y estoy haciendo todo lo posible para evitar preguntar, pero este me vuelve loco. Hice una aplicación Wiki con un tema y un modelo de categoría. Lo conecté a un Sitio en mi CMS y lo agregué a mi Menú. Ahora me gustaría poder mostrar todas las categorías de nivel superior, sus categorías y temas secundarios y las categorías secundarias de estos, y demás, en mi menú.

Menu/Navigation should look like this: Wiki Category1 Category1.1 Topic Category1.2 Topic Category2 Topic Category3 ... Right now i can only show the Top categories: Wiki Category1 Category2 Category3

Ya creé un menu.py para obtener un SubMenú personalizado en mi Wiki (el que ves arriba):

menu.py class WikiSubMenu(CMSAttachMenu): name = _("Wiki Sub-Menu") def get_nodes(self, request): nodes = [] categories = Category.objects.filter(parent_id__isnull=True) for c in categories: node = NavigationNode( mark_safe(c.name), c.get_absolute_url(), c.id, ) nodes.append(node) return nodes menu_pool.register_menu(WikiSubMenu)

Mi modelo de categoría:

class Category(models.Model): '''''' Category model. '''''' name = models.CharField(max_length=100) slug = models.SlugField(unique=True) description = models.TextField(blank=True) parent = models.ForeignKey( ''self'', null=True, blank=True, related_name=''children'' ) sort = models.IntegerField(default=0) class Meta: ordering = [''sort'', ''name''] def __unicode__(self): return self.name @models.permalink def get_absolute_url(self): return (''topics:categories_category_detail'', (), {''slug'': self.slug}) def get_all_children(self): return Category.objects.filter(parent=self)

Ahora, ¿es posible crear un Sub-SubMenú, para todas las Categorías con Childs, sus Childs y sus Childs, y así sucesivamente?

Gracias por su ayuda y perdón por el mal inglés

- EDITAR: -

Acabo de encontrar eso:

docs.django-cms.org/en/3.0.6/extending_cms/app_integration.html#integration-modifiers

(Se eliminó el enlace directo para agregar 2 enlaces nuevos, lo siento)

Creo que eso es lo que estoy buscando, estaba algo ciega y no lo encontré. Lo probaré y publicaré la respuesta si funcionó.

- EDITAR (OTRA VEZ): -

El modificador no funcionó para mí, pero obtuve una pieza más completa, leí Docs nuevamente, y descubrí que puedo darle a NavigationNodes un attr dictonary opcional, que llené con todas las categorías con parent = c, de esa manera Tenía los datos que necesitaba, y luego encontré ese menú desplegable de bootstrap realmente bueno, que hace exactamente lo que quería. Entonces mi código hasta ahora se ve así:

menu.py class TopicsSubMenu(CMSAttachMenu): name = _("Wiki Sub-Menu") def get_nodes(self, request): nodes = [] categories = Category.objects.filter(parent_id__isnull=True) for c in categories: node = NavigationNode( mark_safe(c.name), c.get_absolute_url(), c.pk, attr=dict( subcategories=Category.objects.filter(parent=c),), ) nodes.append(node) return nodes

Y mi plantilla:

menu.html {% for child in children %} <li> {% if child.children %} <a class="dropdown-toggle" data-toggle="dropdown" href="#"> {{ child.get_menu_title }} <span class="caret"> </span> </a> <ul class="dropdown-menu multi-level" role="menu" aria-labelledby="dropdownMenu"> {% for child in child.children %} {% if child.attr.subcategories.count %} <li class="dropdown-submenu"> <a tabindex="-1" href="#">{{ child.get_menu_title }}</a> <ul class="dropdown-menu"> {% for subcategory in child.attr.subcategories %} <li> <a tabindex="-1" href="{{ subcategory.get_absolute_url }}">{{ subcategory }}</a> </li> {% endfor %} </ul> </li> {% else %} <li><a href="{{child.get_absolute_url}}">{{ child.get_menu_title }}</li></a> {% endif %} {% endfor %} </ul> {% else %} <a href="{{ child.get_absolute_url }}"> <span> {{ child.get_menu_title }} </span> </a> {% endif %} </li> {% if class and forloop.last and not forloop.parentloop %} {% endif %} {% endfor %}

Mi siguiente paso será escribir todo el ciclo "for" de la plantilla en un Método, hacerlo recursivo con un ciclo while o algo así y publicar el resultado como Respuesta.

Espero poder ayudar a alguien con esas cosas :)