EDIT: (See end of post for the original text of the answer with the initial, simple idea.)
After being kindly stricken with a cluebat (see the OP's comment below), I find I can see more to the problem than before. Sorry it took so long. Anyway:
Would this kind of template be alright for you?
{% for mi in dyn_menu_items %}
{% if mi.authorised %}
<a href={{ mi.url }}>{{ mi.title }}</a>
{% endif %}
{% endfor %}
To make this work on the Python side, you could use RequestContext
in your views with a custom context processor setting the dyn_menu_items
variable appropriately. In case some background information is required, the Advanced Templates chapter of the Django Book introduces RequestContext
, shows how to use it with render_to_response
(kinda important :-)) etc.
Also, I guess at this point it could be useful to put the view functions responsible for the locked-up sections of your site in a list somewhere:
_dyn_menu_items = [(url1, view1, title1, perm1), ...]
Then you could map
a couple of functions, say prepare_pattern
and prepare_menu_item
across that list, having it work roughly like so:
def prepare_pattern(menu_item):
url1, view, title, perm = menu_item
pattern = PREPARE_URLCONF_ENTRY_SOMEHOW(...) # fill in as appropriate
return pattern
def prepare_menu_item(menu_item):
url, view, title, perm = menu_item
mi = PREPARE_THE_BIT_FOR_REQUESTCONTEXT(...) # as above
return mi
These could be combined into a single function, of course, but not everybody would find the result more readable... Anyway, the output of map(prepare_menu_item, _dyn_menu_items)
would need to be a dictionary to be passed to your views by a helpful context processor (the figuring out of which, it being the slightly tedious bit here, I'll leave to you ;-)), whereas the output of map(prepare_pattern, _dyn_menu_items)
, let's call it dyn_menu_patterns
, would be used in patterns('', *dyn_menu_patterns)
, to be used in your URLconf.
I hope this makes sense and is of some help...
THE PRE-EDIT ANSWER:
Based on your short description, I'm not sure what solution would be best for you... But if the permission_required
snippet does what you want, just not DRY-ly enough, how about rolling your own wrapper:
def ask_to_login(perm, view):
return permission_required(perm, login_url='/loginpage/', view)
You could put this anywhere, including in URLconf. Then you could replace all mentions of '/loginpage/'
with reference to a variable defined towards the top of your URLs file and you'd have yourself a solution with a single mention of the actual login URL, for one-place-only update of said URL should you have to move it around. :-)
Of course the views would still need to be wrapped explicitly; if that bothers you, you could try to make ask_to_login
into a decorator for easy wrapping at the definition site. (But perhaps it's really best not to do it, lest you force yourself to dig your views from under the decorator in case you need them undecorated at some point in the future.)