Skip to content

Commit

Permalink
Merge branch 'master' into menus_api
Browse files Browse the repository at this point in the history
  • Loading branch information
ababic authored Jun 19, 2019
2 parents d08866a + 0e5ba4c commit c0ba2ee
Show file tree
Hide file tree
Showing 33 changed files with 432 additions and 351 deletions.
42 changes: 20 additions & 22 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,44 +1,42 @@
language: python
cache: pip
dist: trusty

matrix:
include:
include:
- env: TOXENV=py34-dj111-wt2
sudo: false
dist: trusty
python: 3.4
- env: TOXENV=py35-dj111-wt2
sudo: false
dist: trusty
python: 3.5
- env: TOXENV=py36-dj111-wt2
sudo: false
dist: trusty
python: 3.6
- env: TOXENV=py36-dj2-wt21
sudo: false
dist: trusty
python: 3.6
- env: TOXENV=py36-dj2-wt22
sudo: false
dist: trusty
python: 3.6
- env: TOXENV=py36-dj21-wt23
sudo: false
dist: trusty
python: 3.6
- env: TOXENV=py37-dj111-wt2
dist: xenial
python: 3.7
- env: TOXENV=py37-dj2-wt21
dist: xenial
python: 3.7
- env: TOXENV=py37-dj2-wt22
dist: xenial
python: 3.7
- env: TOXENV=py37-dj21-wt23
sudo: true
dist: xenial
python: 3.7
- env: TOXENV=py37-dj21-wt24
dist: xenial
python: 3.7
- env: TOXENV=py37-dj22-wt25
dist: xenial
python: 3.7


install:
- pip install tox codecov

script:
- tox

after_success:
after_success:
- codecov

deploy:
Expand All @@ -50,4 +48,4 @@ deploy:
tags: true
branch: master
repo: rkhleics/wagtailmenus
condition: "$TOXENV = py37-dj21-wt23"
condition: "$TOXENV = py37-dj22-wt25"
179 changes: 106 additions & 73 deletions CHANGELOG.md

Large diffs are not rendered by default.

3 changes: 3 additions & 0 deletions CONTRIBUTORS.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
* Pierre Manceaux (pierremanceaux)
* Michael van de Waeter (mvdwaeter)
* Philipp Bosch (philippbosch) (A Color Bright)
* Oktay Altay (OktayAltay)
* Dan Bentley (danbentley)


## Translators
Expand All @@ -34,3 +36,4 @@
* Clarice Bianchini (claricebbcosta)
* Jérôme Lebleu (jeromelebleu)
* José Luis (SalahAdDin)
* Abdulaziz Alfuhigi (3bdul3ziz)
10 changes: 5 additions & 5 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,22 @@
.. image:: https://codecov.io/gh/rkhleics/wagtailmenus/branch/master/graph/badge.svg
:alt: Code coverage
:target: https://codecov.io/gh/rkhleics/wagtailmenus

.. image:: https://readthedocs.org/projects/wagtailmenus/badge/?version=stable
:alt: Documentation Status
:target: http://wagtailmenus.readthedocs.io/en/stable/?badge=stable


============
wagtailmenus
============

wagtailmenus is an extension for Torchbox's `Wagtail CMS <https://github.com/torchbox/wagtail>`_ to help you manage and render multi-level navigation and simple flat menus in a consistent, flexible way.

The current version is tested for compatiblily with the following:
The current version is tested for compatiblily with the following:

- Wagtail versions 2.0 to 2.3
- Django versions 1.11 to 2.1
- Wagtail versions 2.0 to 2.5
- Django versions 1.11 to 2.2
- Python versions 3.4 to 3.7

.. image:: https://raw.githubusercontent.com/rkhleics/wagtailmenus/master/docs/source/_static/images/repeating-item.png
Expand Down
64 changes: 32 additions & 32 deletions docs/source/advanced_topics/custom_menu_classes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ Using custom menu classes and models

.. _custom_main_menu_models:

Overriding the models used for main menus
Overriding the models used for main menus
=========================================

There are a couple of different approaches for overriding the models used for defining / rendering main menus. The best approach for your project depends on which models you need to override.
Expand All @@ -23,11 +23,11 @@ Replacing the ``MainMenuItem`` model only

If you're happy with the default ``MainMenu`` model, but wish customise the menu item model (e.g. to add images, description fields, or extra fields for translated strings), you can use the :ref:`MAIN_MENU_ITEMS_RELATED_NAME` setting to have main menus use a different model, both within Wagtail's CMS, and for generating the list of ``menu_items`` used by menu templates.

1. Within your project, define your custom model by subclassing
1. Within your project, define your custom model by subclassing
``AbstractMainMenuItem``:

.. code-block:: python
# appname/models.py
from django.db import models
Expand Down Expand Up @@ -71,7 +71,7 @@ If you're happy with the default ``MainMenu`` model, but wish customise the menu
)
2. Create migrations for the new model by running:

.. code-block:: console
python manage.py makemigrations appname
Expand All @@ -90,7 +90,7 @@ If you're happy with the default ``MainMenu`` model, but wish customise the menu
# Set this to the 'related_name' attribute used on the ParentalKey field
WAGTAILMENUS_MAIN_MENU_ITEMS_RELATED_NAME = "custom_menu_items"
5. *That's it!* The custom models will now be used instead of the default ones.
5. *That's it!* The custom models will now be used instead of the default ones.

.. NOTE::
Although you won't be able to see them in the CMS any longer, the default models and any data that was in the original database table will remain intact.
Expand All @@ -101,11 +101,11 @@ Replacing both the ``MainMenu`` and ``MainMenuItem`` models

If you also need to override the ``MainMenu`` model, that's possible too. But, because the ``MainMenuItem`` model is tied to ``MainMenu``, you'll also need to create custom menu item model (whether you wish to add fields / change their behaviour, or not).

1. Within your project, define your custom models by subclassing the
1. Within your project, define your custom models by subclassing the
``AbstractMainMenu`` and ``AbstractMainMenuItem`` model classes:

.. code-block:: python
# appname/models.py
from django.db import models
Expand All @@ -114,7 +114,7 @@ If you also need to override the ``MainMenu`` model, that's possible too. But, b
from django.utils import timezone
from modelcluster.fields import ParentalKey
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel
from wagtailmenus import app_settings
from wagtailmenus.conf import settings
from wagtailmenus.models import AbstractMainMenu, AbstractMainMenuItem
Expand Down Expand Up @@ -157,11 +157,11 @@ If you also need to override the ``MainMenu`` model, that's possible too. But, b
menu = ParentalKey(
LimitedMainMenu, # we can use the model from above
on_delete=models.CASCADE,
related_name=app_settings.MAIN_MENU_ITEMS_RELATED_NAME,
related_name=settings.MAIN_MENU_ITEMS_RELATED_NAME,
)
2. Create migrations for the new models by running:

.. code-block:: console
python manage.py makemigrations appname
Expand All @@ -176,12 +176,12 @@ If you also need to override the ``MainMenu`` model, that's possible too. But, b
model instead of the default one. e.g:

.. code-block:: python
# settings.py
WAGTAILMENUS_MAIN_MENU_MODEL = "appname.LimitedMainMenu"
5. *That's it!* The custom models will now be used instead of the default ones.
5. *That's it!* The custom models will now be used instead of the default ones.

.. NOTE::
Although you won't be able to see them in the CMS any longer, the default models and any data that was in the original database table will remain intact.
Expand All @@ -200,9 +200,9 @@ Replacing the ``FlatMenuItem`` model only
If you're happy with the default ``FlatMenu`` model, but wish customise the menu item models (e.g. to add images, description fields, or extra fields for translated strings), you can use the :ref:`FLAT_MENU_ITEMS_RELATED_NAME` setting to have flat menus use a different model, both within Wagtail's CMS, and for generating the list of ``menu_items`` used by menu templates.

1. Within your project, define your custom model by subclassing ``AbstractFlatMenuItem``:

.. code-block:: python
# apname/models.py
from django.db import models
Expand Down Expand Up @@ -246,7 +246,7 @@ If you're happy with the default ``FlatMenu`` model, but wish customise the menu
)
2. Create migrations for the new models by running:

.. code-block:: console
python manage.py makemigrations appname
Expand All @@ -261,7 +261,7 @@ If you're happy with the default ``FlatMenu`` model, but wish customise the menu
instead of the default one. e.g:

.. code-block:: python
# settings.py
# Use the 'related_name' attribute you used on your custom model's ParentalKey field
Expand All @@ -278,26 +278,26 @@ Replacing both the ``FlatMenu`` and ``FlatMenuItem`` models

If you also need to override the ``FlatMenu`` model, that's possible too. But, because the ``FlatMenuItem`` model is tied to ``FlatMenu``, you'll also need to create custom menu item model (whether you wish to add fields or their behaviour or not).

1. Within your project, define your custom models by subclassing the
1. Within your project, define your custom models by subclassing the
``AbstractFlatMenu`` and ``AbstractFlatMenuItem`` model classes:

.. code-block:: python
# appname/models.py
from django.db import models
from django.utils import translation
from django.utils.translation import ugettext_lazy as _
from modelcluster.fields import ParentalKey
from wagtail.wagtailadmin.edit_handlers import FieldPanel, MultiFieldPanel, PageChooserPanel
from wagtailmenus import app_settings
from wagtailmenus.conf import settings
from wagtailmenus.panels import FlatMenuItemsInlinePanel
from wagtailmenus.models import AbstractFlatMenu, AbstractFlatMenuItem
class TranslatedField(object):
"""
A class that can be used on models to return a 'field' in the
A class that can be used on models to return a 'field' in the
desired language, where there a multiple versions of a field to
cater for multiple languages (in this case, English, German & French)
"""
Expand Down Expand Up @@ -358,7 +358,7 @@ If you also need to override the ``FlatMenu`` model, that's possible too. But, b
menu = ParentalKey(
TranslatedFlatMenu, # we can use the model from above
on_delete=models.CASCADE,
related_name=app_settings.FLAT_MENU_ITEMS_RELATED_NAME,
related_name=settings.FLAT_MENU_ITEMS_RELATED_NAME,
)
link_text_de = models.CharField(
verbose_name=_("link text (german)"),
Expand All @@ -377,7 +377,7 @@ If you also need to override the ``FlatMenu`` model, that's possible too. But, b
"""Use `translated_link_text` instead of just `link_text`"""
return self.translated_link_text or getattr(
self.link_page,
app_settings.PAGE_FIELD_FOR_MENU_ITEM_TEXT,
settings.PAGE_FIELD_FOR_MENU_ITEM_TEXT,
self.link_page.title
)
Expand All @@ -395,7 +395,7 @@ If you also need to override the ``FlatMenu`` model, that's possible too. But, b
)
2. Create migrations for the new models by running:

.. code-block:: console
python manage.py makemigrations appname
Expand All @@ -410,12 +410,12 @@ If you also need to override the ``FlatMenu`` model, that's possible too. But, b
menu model instead of the default one. e.g:

.. code-block:: python
# settings.py
WAGTAILMENUS_FLAT_MENU_MODEL = "appname.TranslatedFlatMenu"
5. That's it! The custom models will now be used instead of the default ones.
5. That's it! The custom models will now be used instead of the default ones.

.. NOTE::
Although you won't be able to see them in the CMS any longer, the
Expand All @@ -433,7 +433,7 @@ Like the ``main_menu`` and ``flat_menu`` tags, the ``section_menu`` tag uses a `
The class ``wagtailmenus.models.menus.SectionMenu`` is used by default, but you can use the ``WAGTAILMENUS_SECTION_MENU_CLASS`` setting in your project to make wagtailmenus use an alternative class (for example, if you want to modify the base queryset that determines which pages should be included when rendering). To implement a custom classes, it's recommended that you subclass the ``SectionMenu`` and override any methods as required, like in the following example:

.. code-block:: python
# mysite/appname/models.py
from django.utils.translation import ugettext_lazy as _
Expand All @@ -442,17 +442,17 @@ The class ``wagtailmenus.models.menus.SectionMenu`` is used by default, but you
class CustomSectionMenu(SectionMenu):
def get_base_page_queryset(self):
# Show draft and expired pages in menu for superusers
if self.request.user.is_superuser:
return Page.objects.filter(show_in_menus=True)
# Resort to default behaviour for everybody else
return super(CustomSectionMenu, self).get_base_page_queryset()
.. code-block:: python
# settings.py
WAGTAILMENUS_SECTION_MENU_CLASS = "mysite.appname.models.CustomSectionMenu"
Expand All @@ -468,7 +468,7 @@ Like all of the other tags, the ``children_menu`` tag uses a ``Menu`` class to f
The class ``wagtailmenus.models.menus.ChildrenMenu`` is used by default, but you can use the ``WAGTAILMENUS_CHILDREN_MENU_CLASS`` setting in your project to make wagtailmenus use an alternative class (for example, if you want to modify which pages are included). For custom classes, it's recommended that you subclass ``ChildrenMenu`` and override any methods as required e.g:

.. code-block:: python
# appname/menus.py
from django.utils.translation import ugettext_lazy as _
Expand All @@ -486,7 +486,7 @@ The class ``wagtailmenus.models.menus.ChildrenMenu`` is used by default, but you
.. code-block:: python
# settings.py
WAGTAILMENUS_CHILDREN_MENU_CLASS = "mysite.appname.models.CustomChildrenMenu"
Expand Down
14 changes: 7 additions & 7 deletions docs/source/advanced_topics/specific_pages.rst
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,22 @@

For pages, Wagtail makes use of a technique in Django called 'multi-table inheritance'. In simple terms, this means that when you create an instance of a custom page type model, the data is saved in two different database tables:

* All of the standard fields from Wagtail's ``Page`` model are stored in one table
* Any data for additional fields specific to your custom model are saved in another one
* All of the standard fields from Wagtail's ``Page`` model are stored in one table.
* Any data for additional fields specific to your custom model are saved in another table.

Because of this, in order for Django to return 'specific' page type instance (e.g. an `EventPage`), it needs to fetch and join data from both tables; which has a negative effect on performance.
Because of this, in order for Django to return a 'specific' page type instance (e.g. an `EventPage`), it needs to fetch and join data from both tables, which has a negative effect on performance.

Menu generation is particularly resource intensive, because a menu needs to know a lot of data about a lot of pages. Add a need for 'specific' page instances to that mix (perhaps you need to access multilingual field values that only exist in the specific database table, or you want to use other custom field values in your menu templates), and that intensity is understandably greater, as the data will likely be spread over many tables (depending on how many custom page types you are using), needing lots of database joins to put everything together.
Menu generation is particularly resource intensive because a menu needs to know a lot of data about a lot of pages. Add into that mix a need to retrieve 'specific' page instances (perhaps you need to access multilingual field values that only exist in a specific database table, or maybe you want to use other custom field values in your menu templates), and that intensity is understandably greater, as the data will likely be spread over many tables (depending on how many custom page types you are using), requiring lots of database joins to put everything together.

Because every project has different needs, wagtailmenus gives you some fine grained control over how 'specific' pages should be used in your menus. When defining a ``MainMenu`` or ``FlatMenu`` in the CMS, the **Specific page use** field allows you to choose one of the following options, which can also be passed to any of the included template tags using the ``use_specific`` parameter.
Because every project has different needs, wagtailmenus gives you some fine-grained control over how 'specific' pages should be used in your menus. When defining a ``MainMenu`` or ``FlatMenu`` in the CMS, the **Specific page usage** field allows you to choose one of the following options, which can also be passed to any of the included template tags using the ``use_specific`` parameter.


.. _specific_pages_values:

Supported values for fetching specific pages
--------------------------------------------

* **Off** (value: ``0``): Use only standard ``Page`` model data and methods, and make the minimum number of database methods when rendering. If you aren't using wagtailmenus' ``MenuPage`` model in your project, and don't need to access any custom page model fields or methods in you menu templates, and aren't overriding ``get_url_parts()`` or other ``Page`` methods concerned with URL generation, you should use this option for optimal performance.
* **Off** (value: ``0``): Use only standard ``Page`` model data and methods, and make the minimum number of database calls when rendering. If you aren't using wagtailmenus' ``MenuPage`` model in your project, and you don't need to access any custom page model fields or methods in your menu templates, and if you aren't overriding ``get_url_parts()`` or other ``Page`` methods concerned with URL generation, you should use this option for optimal performance.

* **Auto** (value: ``1``): Only fetch and use specific pages when needed for ``MenuPage`` operations (e.g. for 'repeating menu item' behaviour, and manipulation of sub-menu items via ``has_submenu_items()`` and ``modify_submenu_items()`` methods).

Expand All @@ -40,7 +40,7 @@ Supported values for fetching specific pages
Using the ``use_specific`` template tag argument
------------------------------------------------

All of the template tags included in wagtailmenus accept a ``use_specific`` argument, allowing you to override any default settings, or the settings applied via the CMS to individual ``MainMenu`` and ``FlatMenu`` objects. As a value, you can pass in the integer value of any of the above options, for example:
All of the template tags included in wagtailmenus accept a ``use_specific`` argument, allowing you to override any default settings or the settings applied via the CMS to individual ``MainMenu`` and ``FlatMenu`` objects. As a value, you can pass in the integer value of any of the above options, for example:

.. code-block:: html

Expand Down
Loading

0 comments on commit c0ba2ee

Please sign in to comment.