11from cms .cms_toolbars import (
22 BasicToolbar ,
3+ PageToolbar ,
34 ADMIN_MENU_IDENTIFIER ,
45 ADMINISTRATION_BREAK ,
56 USER_SETTINGS_BREAK ,
67 TOOLBAR_DISABLE_BREAK ,
78 SHORTCUTS_BREAK ,
89 CLIPBOARD_BREAK ,
910)
11+ from cms .utils .page_permissions import (
12+ user_can_change_page ,
13+ user_can_delete_page ,
14+ user_can_publish_page ,
15+ )
16+ from cms .constants import TEMPLATE_INHERITANCE_MAGIC
1017from cms .utils .conf import get_cms_setting
11- from cms .utils .urlutils import admin_reverse
18+ from cms .utils .urlutils import add_url_parameters , admin_reverse
19+ from cms .utils import get_language_from_request , page_permissions
1220
1321from django .contrib .auth .models import Permission
1422from django .contrib .sites .models import Site
2230
2331from cms .models import Page
2432
25- from gsoc .models import ArticleReview , UserProfile
33+ from gsoc .models import ArticleReview
34+
35+
36+ # identifiers
37+ PAGE_MENU_IDENTIFIER = 'page'
38+ PAGE_MENU_ADD_IDENTIFIER = 'add_page'
39+ PAGE_MENU_FIRST_BREAK = 'Page Menu First Break'
40+ PAGE_MENU_SECOND_BREAK = 'Page Menu Second Break'
41+ PAGE_MENU_THIRD_BREAK = 'Page Menu Third Break'
42+ PAGE_MENU_FOURTH_BREAK = 'Page Menu Fourth Break'
43+ PAGE_MENU_LAST_BREAK = 'Page Menu Last Break'
44+ TEMPLATE_MENU_BREAK = 'Template Menu Break'
2645
2746
2847def add_admin_menu (self ):
@@ -47,7 +66,7 @@ def add_admin_menu(self):
4766 sites_menu .add_sideframe_item (
4867 _ ("Admin Sites" ), url = admin_reverse ("sites_site_changelist" )
4968 )
50- sites_menu .add_break (ADMIN_SITES_BREAK )
69+ sites_menu .add_break (ADMINISTRATION_BREAK )
5170 for site in sites_queryset :
5271 sites_menu .add_link_item (
5372 site .name ,
@@ -56,9 +75,10 @@ def add_admin_menu(self):
5675 )
5776
5877 # admin
59- self ._admin_menu .add_sideframe_item (
60- _ ("Administration" ), url = admin_reverse ("index" )
61- )
78+ if user and user .is_superuser :
79+ self ._admin_menu .add_sideframe_item (
80+ _ ("Administration" ), url = admin_reverse ("index" )
81+ )
6282
6383 # scheduler
6484 if user and user .is_superuser :
@@ -109,7 +129,7 @@ def add_admin_menu(self):
109129 )
110130 self ._admin_menu .add_break (USER_SETTINGS_BREAK )
111131 # clipboard
112- if self .toolbar .edit_mode_active :
132+ if user and user . is_superuser and self .toolbar .edit_mode_active :
113133 # True if the clipboard exists and there's plugins in it.
114134 clipboard_is_bound = self .toolbar .clipboard_plugin
115135
@@ -128,10 +148,11 @@ def add_admin_menu(self):
128148 self ._admin_menu .add_break (CLIPBOARD_BREAK )
129149
130150 # Disable toolbar
131- self ._admin_menu .add_link_item (
132- _ ("Disable toolbar" ),
133- url = "?%s" % get_cms_setting ("CMS_TOOLBAR_URL__DISABLE" ),
134- )
151+ if user and user .is_superuser :
152+ self ._admin_menu .add_link_item (
153+ _ ("Disable toolbar" ),
154+ url = "?%s" % get_cms_setting ("CMS_TOOLBAR_URL__DISABLE" ),
155+ )
135156 self ._admin_menu .add_break (TOOLBAR_DISABLE_BREAK )
136157 self ._admin_menu .add_link_item (
137158 _ ("Shortcuts..." ), url = "#" , extra_classes = ("cms-show-shortcuts" ,)
@@ -166,6 +187,285 @@ def populate(self):
166187BasicToolbar .populate = populate
167188
168189
190+ def add_page_menu (self ):
191+ user = getattr (self .request , "user" , None )
192+ if user and user .is_superuser :
193+ if self .page :
194+ edit_mode = self .toolbar .edit_mode_active
195+ refresh = self .toolbar .REFRESH_PAGE
196+ can_change = user_can_change_page (
197+ user = self .request .user ,
198+ page = self .page ,
199+ site = self .current_site ,
200+ )
201+
202+ # menu for current page
203+ # NOTE: disabled if the current path is "deeper" into the
204+ # application's url patterns than its root. This is because
205+ # when the Content Manager is at the root of the app-hook,
206+ # some of the page options still make sense.
207+ current_page_menu = self .toolbar .get_or_create_menu (
208+ PAGE_MENU_IDENTIFIER ,
209+ _ ('Page' ), position = 1 ,
210+ disabled = self .in_apphook () and not self .in_apphook_root ()
211+ )
212+
213+ new_page_params = {'edit' : 1 }
214+ new_sub_page_params = {'edit' : 1 , 'parent_node' : self .page .node_id }
215+
216+ if self .page .is_page_type :
217+ add_page_url = admin_reverse ('cms_pagetype_add' )
218+ advanced_url = admin_reverse ('cms_pagetype_advanced' , args = (self .page .pk ,))
219+ page_settings_url = admin_reverse ('cms_pagetype_change' , args = (self .page .pk ,))
220+ duplicate_page_url = admin_reverse ('cms_pagetype_duplicate' , args = [self .page .pk ])
221+ else :
222+ add_page_url = admin_reverse ('cms_page_add' )
223+ advanced_url = admin_reverse ('cms_page_advanced' , args = (self .page .pk ,))
224+ page_settings_url = admin_reverse ('cms_page_change' , args = (self .page .pk ,))
225+ duplicate_page_url = admin_reverse ('cms_page_duplicate' , args = [self .page .pk ])
226+
227+ can_add_root_page = page_permissions .user_can_add_page (
228+ user = self .request .user ,
229+ site = self .current_site ,
230+ )
231+
232+ if self .page .parent_page :
233+ new_page_params ['parent_node' ] = self .page .parent_page .node_id
234+ can_add_sibling_page = page_permissions .user_can_add_subpage (
235+ user = self .request .user ,
236+ target = self .page .parent_page ,
237+ )
238+ else :
239+ can_add_sibling_page = can_add_root_page
240+
241+ can_add_sub_page = page_permissions .user_can_add_subpage (
242+ user = self .request .user ,
243+ target = self .page ,
244+ )
245+
246+ # page operations menu
247+ add_page_menu = current_page_menu .get_or_create_menu (
248+ PAGE_MENU_ADD_IDENTIFIER ,
249+ _ ('Create Page' ),
250+ )
251+
252+ add_page_menu_modal_items = (
253+ (_ ('New Page' ), new_page_params , can_add_sibling_page ),
254+ (_ ('New Sub Page' ), new_sub_page_params , can_add_sub_page ),
255+ )
256+
257+ for title , params , has_perm in add_page_menu_modal_items :
258+ params .update (language = self .toolbar .request_language )
259+ add_page_menu .add_modal_item (
260+ title ,
261+ url = add_url_parameters (add_page_url , params ),
262+ disabled = not has_perm ,
263+ )
264+
265+ add_page_menu .add_modal_item (
266+ _ ('Duplicate this Page' ),
267+ url = add_url_parameters (
268+ duplicate_page_url ,
269+ {'language' : self .toolbar .request_language }
270+ ),
271+ disabled = not can_add_sibling_page ,
272+ )
273+
274+ # first break
275+ current_page_menu .add_break (PAGE_MENU_FIRST_BREAK )
276+
277+ # page edit
278+ page_edit_url = '?%s' % get_cms_setting ('CMS_TOOLBAR_URL__EDIT_ON' )
279+ current_page_menu .add_link_item (
280+ _ ('Edit this Page' ),
281+ disabled = edit_mode ,
282+ url = page_edit_url
283+ )
284+
285+ # page settings
286+ page_settings_url = add_url_parameters (
287+ page_settings_url ,
288+ language = self .toolbar .request_language
289+ )
290+ settings_disabled = not edit_mode or not can_change
291+ current_page_menu .add_modal_item (
292+ _ ('Page settings' ),
293+ url = page_settings_url ,
294+ disabled = settings_disabled ,
295+ on_close = refresh
296+ )
297+
298+ # advanced settings
299+ advanced_url = add_url_parameters (
300+ advanced_url ,
301+ language = self .toolbar .request_language
302+ )
303+ can_change_advanced = self .page .has_advanced_settings_permission (self .request .user )
304+ advanced_disabled = not edit_mode or not can_change_advanced
305+ current_page_menu .add_modal_item (
306+ _ ('Advanced settings' ),
307+ url = advanced_url ,
308+ disabled = advanced_disabled
309+ )
310+
311+ # templates menu
312+ if edit_mode :
313+ if self .page .is_page_type :
314+ action = admin_reverse ('cms_pagetype_change_template' , args = (self .page .pk ,))
315+ else :
316+ action = admin_reverse ('cms_page_change_template' , args = (self .page .pk ,))
317+
318+ if can_change_advanced :
319+ templates_menu = current_page_menu .get_or_create_menu (
320+ 'templates' ,
321+ _ ('Templates' ),
322+ disabled = not can_change ,
323+ )
324+
325+ for path , name in get_cms_setting ('TEMPLATES' ):
326+ active = self .page .template == path
327+ if path == TEMPLATE_INHERITANCE_MAGIC :
328+ templates_menu .add_break (TEMPLATE_MENU_BREAK )
329+ templates_menu .add_ajax_item (
330+ name ,
331+ action = action ,
332+ data = {'template' : path },
333+ active = active ,
334+ on_success = refresh
335+ )
336+
337+ # page type
338+ if not self .page .is_page_type :
339+ page_type_url = admin_reverse ('cms_pagetype_add' )
340+ page_type_url = add_url_parameters (
341+ page_type_url ,
342+ source = self .page .pk ,
343+ language = self .toolbar .request_language
344+ )
345+ page_type_disabled = not edit_mode or not can_add_root_page
346+ current_page_menu .add_modal_item (
347+ _ ('Save as Page Type' ),
348+ page_type_url ,
349+ disabled = page_type_disabled
350+ )
351+
352+ # second break
353+ current_page_menu .add_break (PAGE_MENU_SECOND_BREAK )
354+
355+ # permissions
356+ if self .permissions_activated :
357+ permissions_url = admin_reverse ('cms_page_permissions' , args = (self .page .pk ,))
358+ permission_disabled = not edit_mode
359+
360+ if not permission_disabled :
361+ permission_disabled = not \
362+ page_permissions .user_can_change_page_permissions (
363+ user = self .request .user ,
364+ page = self .page ,
365+ )
366+ current_page_menu .add_modal_item (
367+ _ ('Permissions' ),
368+ url = permissions_url ,
369+ disabled = permission_disabled
370+ )
371+
372+ if not self .page .is_page_type :
373+ # dates settings
374+ dates_url = admin_reverse ('cms_page_dates' , args = (self .page .pk ,))
375+ current_page_menu .add_modal_item (
376+ _ ('Publishing dates' ),
377+ url = dates_url ,
378+ disabled = (not edit_mode or not can_change ),
379+ )
380+
381+ # third break
382+ current_page_menu .add_break (PAGE_MENU_THIRD_BREAK )
383+
384+ # navigation toggle
385+ nav_title = _ ('Hide in navigation' ) if self .page .in_navigation \
386+ else _ ('Display in navigation' )
387+ nav_action = admin_reverse (
388+ 'cms_page_change_innavigation' ,
389+ args = (self .page .pk ,)
390+ )
391+ current_page_menu .add_ajax_item (
392+ nav_title ,
393+ action = nav_action ,
394+ disabled = (not edit_mode or not can_change ),
395+ on_success = refresh ,
396+ )
397+
398+ # publisher
399+ if self .title and not self .page .is_page_type :
400+ if self .title .published :
401+ publish_title = _ ('Unpublish page' )
402+ publish_url = admin_reverse (
403+ 'cms_page_unpublish' ,
404+ args = (self .page .pk , self .current_lang )
405+ )
406+ else :
407+ publish_title = _ ('Publish page' )
408+ publish_url = admin_reverse (
409+ 'cms_page_publish_page' ,
410+ args = (self .page .pk , self .current_lang )
411+ )
412+
413+ user_can_publish = user_can_publish_page (self .request .user , page = self .page )
414+ current_page_menu .add_ajax_item (
415+ publish_title ,
416+ action = publish_url ,
417+ disabled = not edit_mode or not user_can_publish ,
418+ on_success = refresh ,
419+ )
420+
421+ if self .current_lang and not self .page .is_page_type :
422+ # revert to live
423+ current_page_menu .add_break (PAGE_MENU_FOURTH_BREAK )
424+ revert_action = admin_reverse (
425+ 'cms_page_revert_to_live' ,
426+ args = (self .page .pk , self .current_lang )
427+ )
428+ revert_question = _ ('Are you sure you want to revert to live?' )
429+ # Only show this action if the page has pending changes and a public version
430+ is_enabled = (
431+ edit_mode
432+ and can_change
433+ and self .page .is_dirty (self .current_lang )
434+ and self .page .publisher_public
435+ )
436+ current_page_menu .add_ajax_item (
437+ _ ('Revert to live' ),
438+ action = revert_action ,
439+ question = revert_question ,
440+ disabled = not is_enabled ,
441+ on_success = refresh ,
442+ extra_classes = ('cms-toolbar-revert' ,),
443+ )
444+
445+ # last break
446+ current_page_menu .add_break (PAGE_MENU_LAST_BREAK )
447+
448+ # delete
449+ if self .page .is_page_type :
450+ delete_url = admin_reverse ('cms_pagetype_delete' , args = (self .page .pk ,))
451+ else :
452+ delete_url = admin_reverse ('cms_page_delete' , args = (self .page .pk ,))
453+ delete_disabled = not edit_mode or not user_can_delete_page (
454+ self .request .user ,
455+ page = self .page
456+ )
457+ on_delete_redirect_url = self .get_on_delete_redirect_url ()
458+ current_page_menu .add_modal_item (
459+ _ ('Delete page' ),
460+ url = delete_url ,
461+ on_close = on_delete_redirect_url ,
462+ disabled = delete_disabled
463+ )
464+
465+
466+ PageToolbar .add_page_menu = add_page_menu
467+
468+
169469def populate (self ):
170470 config = self ._NewsBlogToolbar__get_newsblog_config ()
171471 if not config :
0 commit comments