-
Notifications
You must be signed in to change notification settings - Fork 17
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
21 changed files
with
801 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,16 @@ | ||
CHANGELOG | ||
========= | ||
|
||
1.0.1(2017-04-29) | ||
----------------- | ||
|
||
- Added docs | ||
- Readme enhanced | ||
- BUGFIX: Added a correction to the validators evaluation with the AND connector | ||
- Added flake8 to CI | ||
- Added tox | ||
|
||
1.0.0 (2017-04-09) | ||
------------------ | ||
|
||
- Initial release |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,86 @@ | ||
Menu Generation | ||
=============== | ||
|
||
Django Menu Generator uses python dictionaries to represent the menu items, usually a menu item is as follows: | ||
|
||
.. code:: python | ||
{ | ||
"name": 'some name', | ||
"icon_class": 'some icon class', | ||
"url": URL spec, | ||
"validators": [ list of validators ], | ||
"submenu": Dictionary like this | ||
} | ||
Where each key is as follows: | ||
|
||
- ``name``: A string representing the label of the menu item. If you are using i18n here you can pass the name with the ``ugettext_lazy`` function | ||
|
||
- ``icon_class``: A string representing the class of the icon you wish to show on the menu item, e.g you can use font-awesome | ||
|
||
- ``url``: See :doc:`urls` | ||
|
||
- ``validators``: See :doc:`validators` | ||
|
||
- ``submenu``: You can create infinite nested submenus passing here menu items like this | ||
|
||
Django Menu Generator offers two ways to generate the menus, through the Django settings and through each of the Django | ||
apps | ||
|
||
Generating menus through settings | ||
--------------------------------- | ||
|
||
You can add various list dictionaries representing each menu you have as explained in :doc:`usage` | ||
We recommend to have a ``menus.py`` file with the menu list dictionaries and then import it to the settings file if you | ||
go this way | ||
|
||
Generating menus through apps | ||
----------------------------- | ||
|
||
Some people prefer to isolate all the aspects of a project between apps, so, we add this feature to allow the menus | ||
live inside each app. | ||
|
||
You need to add inside the app a ``menus.py`` file that contains a dictionary called ``MENUS``, each element of the | ||
dictionary will be a menu list dictionary with all the configuration needed to display that menu, e.g: | ||
|
||
.. code:: python | ||
MENUS = { | ||
'NAV_MENU_LEFT': [ | ||
{ | ||
"name": "App1 Feature", | ||
"url": "/app1-feature" | ||
} | ||
], | ||
'NAV_MENU_TOP': [ | ||
{ | ||
"name": "Second Menu Feature", | ||
"url": "named_url" | ||
} | ||
] | ||
} | ||
So, as an example, for the ``'NAV_MENU_LEFT'``, Django Menu Generator will loop each app searching for the ``'NAV_MENU_LEFT'`` | ||
list dictionaries inside of the ``MENUS`` and build all the menu configuration to build the whole menu. | ||
|
||
With this feature you can have a project structure like this:: | ||
|
||
your_project/ | ||
├── config_folder/ | ||
│ └── ... | ||
├── app1 | ||
│ └── models.py | ||
│ forms.py | ||
│ views.py | ||
│ menus.py | ||
│ | ||
├── app2 | ||
│ └── models.py | ||
│ forms.py | ||
│ views.py | ||
│ menus.py | ||
│ | ||
... | ||
|
||
You can have a mix of the two approaches if you wish |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,40 @@ | ||
URLs | ||
==== | ||
|
||
You can pass the URL parameters to menu items in three ways. | ||
|
||
Raw URLs | ||
-------- | ||
|
||
A hard-coded url: | ||
|
||
.. code:: python | ||
"url": '/some-path/to-feature' | ||
Reversible URLs | ||
--------------- | ||
|
||
An url that can be reversed with the `reverse` method: | ||
|
||
.. code:: python | ||
"url": 'named_url' | ||
URL with args or kwargs | ||
----------------------- | ||
|
||
e.g. If you have an url with kwargs like this: | ||
|
||
.. code:: python | ||
url(r'^update/(?P<pk>\d+)/$', SomeView.as_view(), name='update'), | ||
you can pass the url as follows: | ||
|
||
"url": {"viewname": 'update', "kwargs": {"pk": 1}} | ||
|
||
In fact, you can pass any of the parameters of the reverse method through the dictionary | ||
|
||
For Django 1.10 the reverse method sign is: ``reverse(viewname, urlconf=None, args=None, kwargs=None, current_app=None)`` | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,123 @@ | ||
Validators | ||
========== | ||
|
||
Django Menu Generator uses validators to allow the displaying of menu items. | ||
|
||
A validator is a function that receives the request as arg and returns a boolean indicating if the check has passed | ||
|
||
for Django Menu Generator the validators must always be a list containing at least one callable or python path to a callable. | ||
If there is more than one validator, all of them will be evaluated using the AND connector. | ||
|
||
Built-in validators | ||
------------------- | ||
|
||
Django Menu Generator has the following built-in validators: | ||
|
||
- is_superuser: | ||
|
||
A validator to check if the authenticated user is a superuser | ||
|
||
Usage: | ||
|
||
.. code:: python | ||
"validators": ['menu_generator.validators.is_superuser'] | ||
- is_staff: | ||
|
||
A validator to check if the authenticated user is member of the staff | ||
|
||
Usage: | ||
|
||
.. code:: python | ||
"validators": ['menu_generator.validators.is_staff'] | ||
- is_authenticated: | ||
|
||
A validator to check if user is authenticated | ||
|
||
Usage: | ||
|
||
.. code:: python | ||
"validators": ['menu_generator.validators.is_authenticated'] | ||
- is_anonymous: | ||
|
||
A validator to check if the user is not authenticated | ||
|
||
Usage: | ||
|
||
.. code:: python | ||
"validators": ['menu_generator.validators.is_anonymous'] | ||
- user_has_permission: | ||
|
||
A validator to check if the user has the given permission | ||
|
||
Usage: | ||
|
||
.. code:: python | ||
"validators": [ | ||
('menu_generator.validators.user_has_permission', 'app_label.permission_codename') | ||
] | ||
- More than one validator: | ||
|
||
You can pass more than one validator to evaluate using the AND connector | ||
|
||
.. code:: python | ||
"validators": [ | ||
'menu_generator.validators.is_staff', | ||
('menu_generator.validators.user_has_permission', 'some_app.some_permission') | ||
... | ||
] | ||
Custom validators | ||
----------------- | ||
|
||
You can build your own validators and use them with Django Menu Generator | ||
|
||
Let's build a validator that checks if the user have more than one pet (dummy example) assuming the user has a | ||
many to many relation called pets | ||
|
||
Assuming we build the function inside ``your_project/app1`` on a ``menu_validators.py`` we have: | ||
|
||
.. code:: python | ||
# Remember you always must to past the request as first parameter | ||
def has_more_than_one_pet(request): | ||
return request.user.pets.count() > 0 | ||
So we can use it as a validator | ||
|
||
.. code:: python | ||
"validators": ['your_project.app1.menu_validators.has_more_than_one_pet'] | ||
Now let's build a validator that checks if the user's pet belongs to a specific type to illustrate the validators with | ||
parameters. | ||
|
||
Assuming we build the function inside the same path and the user have a foreign key called pet | ||
|
||
.. code:: python | ||
def has_a_pet_of_type(request, type): | ||
return request.user.pet.type == type | ||
So we use the validator like this: | ||
|
||
.. code:: python | ||
"validators": [ | ||
('your_project.app1.menu_validators.has_a_pet_of_type', 'DOG') | ||
] | ||
As you can see, we use tuples to pass parameters to the validators, where the first position is the validator and the rest are | ||
the function parameters |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.