From c79f6c48cae9411acf3f413b25d942df34f7719f Mon Sep 17 00:00:00 2001 From: Stephen Burrows Date: Tue, 24 May 2011 18:11:11 -0400 Subject: [PATCH] Added documentation for has_navigation and navigation_host filters. Added examples of Node.navigation use to Navigation docs. Added more human-friendly general docs for shipherd. --- docs/contrib/shipherd.rst | 24 +++++++++++++++++++ philo/contrib/shipherd/models.py | 9 +++++++ .../contrib/shipherd/templatetags/shipherd.py | 2 ++ 3 files changed, 35 insertions(+) diff --git a/docs/contrib/shipherd.rst b/docs/contrib/shipherd.rst index 0f3b59d..915dac8 100644 --- a/docs/contrib/shipherd.rst +++ b/docs/contrib/shipherd.rst @@ -3,6 +3,26 @@ Shipherd .. automodule:: philo.contrib.shipherd :members: + + :class:`.Node`\ s are useful for structuring a website; however, they are inherently unsuitable for creating site navigation. + + The most glaring problem is that a navigation tree based on :class:`.Node`\ s would have one :class:`.Node` as the root, whereas navigation usually has multiple objects at the top level. + + Additionally, navigation needs to have display text that is relevant to the current context; however, :class:`.Node`\ s do not have a field for that, and :class:`.View` subclasses with a name or title field will generally need to use it for database-searchable names. + + Finally, :class:`.Node` structures are inherently unordered, while navigation is inherently ordered. + + :mod:`~philo.contrib.shipherd` exists to resolve these issues by separating navigation structures from :class:`.Node` structures. It is instead structured around the way that site navigation works in the wild: + + * A site may have one or more independent navigation bars (Main navigation, side navigation, etc.) + * A navigation bar may be shared by sections of the website, or even by the entire site. + * A navigation bar has a certain depth that it displays to. + + The :class:`.Navigation` model supplies these features by attaching itself to a :class:`.Node` via :class:`ForeignKey` and adding a :attr:`navigation` property to :class:`.Node` which provides access to a :class:`.Node` instance's inherited :class:`.Navigation`\ s. + + Each entry in the navigation bar is then represented by a :class:`.NavigationItem`, which stores information such as the :attr:`~.NavigationItem.order` and :attr:`~.NavigationItem.text` for the entry. Given an :class:`HttpRequest`, a :class:`.NavigationItem` can also tell whether it :meth:`~.NavigationItem.is_active` or :meth:`~.NavigationItem.has_active_descendants`. + + Since the common pattern is to recurse through a navigation tree and render each part similarly, :mod:`~philo.contrib.shipherd` also ships with the :ttag:`~philo.contrib.shipherd.templatetags.shipherd.recursenavigation` template tag. Models ++++++ @@ -28,3 +48,7 @@ Template tags .. automodule:: philo.contrib.shipherd.templatetags.shipherd .. autotemplatetag:: recursenavigation + +.. autotemplatefilter:: has_navigation + +.. autotemplatefilter:: navigation_host diff --git a/philo/contrib/shipherd/models.py b/philo/contrib/shipherd/models.py index f35be3c..a520fbe 100644 --- a/philo/contrib/shipherd/models.py +++ b/philo/contrib/shipherd/models.py @@ -179,6 +179,15 @@ class Navigation(Entity): """ :class:`Navigation` represents a group of :class:`NavigationItem`\ s that have an intrinsic relationship in terms of navigating a website. For example, a ``main`` navigation versus a ``side`` navigation, or a ``authenticated`` navigation versus an ``anonymous`` navigation. + A :class:`Navigation`'s :class:`NavigationItem`\ s will be accessible from its related :class:`.Node` and that :class:`.Node`'s descendants through a :class:`NavigationMapper` instance at :attr:`Node.navigation`. Example:: + + >>> node.navigation_set.all() + [] + >>> parent = node.parent + >>> items = parent.navigation_set.get(key='main').roots.all() + >>> parent.navigation["main"] == node.navigation["main"] == list(items) + True + """ #: A :class:`NavigationManager` instance. objects = NavigationManager() diff --git a/philo/contrib/shipherd/templatetags/shipherd.py b/philo/contrib/shipherd/templatetags/shipherd.py index 508eace..9e572aa 100644 --- a/philo/contrib/shipherd/templatetags/shipherd.py +++ b/philo/contrib/shipherd/templatetags/shipherd.py @@ -155,6 +155,7 @@ def recursenavigation(parser, token): @register.filter def has_navigation(node, key=None): + """Returns ``True`` if the node has a :class:`.Navigation` with the given key and ``False`` otherwise. If ``key`` is ``None``, returns whether the node has any :class:`.Navigation`\ s at all.""" try: nav = node.navigation if key is not None: @@ -169,6 +170,7 @@ def has_navigation(node, key=None): @register.filter def navigation_host(node, key): + """Returns the :class:`.Node` which hosts the :class:`.Navigation` which ``node`` has inherited for ``key``. Returns ``node`` if any exceptions are encountered.""" try: return Navigation.objects.filter(node__in=node.get_ancestors(include_self=True), key=key).order_by('-node__level')[0].node except: -- 2.20.1