Skip to content
Browse files

Merge branch 'develop' into yakky-feature/multidb_test

Conflicts:
	cms/test_utils/cli.py
	runtests.py
  • Loading branch information...
2 parents 873ac1f + c9b232a commit 8bfcd6f76499f8b901d5098bb23a83fe65a595a0 @digi604 committed Nov 14, 2012
Showing with 9,507 additions and 5,073 deletions.
  1. +5 −0 AUTHORS
  2. +8 −4 CHANGELOG.txt
  3. +1 −1 cms/__init__.py
  4. +17 −44 cms/admin/change_list.py
  5. +0 −13 cms/admin/dialog/forms.py
  6. +4 −18 cms/admin/dialog/views.py
  7. +5 −8 cms/admin/forms.py
  8. +251 −271 cms/admin/pageadmin.py
  9. +1 −9 cms/admin/permissionadmin.py
  10. +28 −44 cms/api.py
  11. +5 −10 cms/appresolver.py
  12. +38 −51 cms/cms_toolbar.py
  13. +0 −3 cms/conf/__init__.py
  14. +0 −4 cms/conf/global_settings.py
  15. +1 −1 cms/conf/patch.py
  16. +4 −0 cms/exceptions.py
  17. +3 −5 cms/forms/utils.py
  18. +21 −20 cms/locale/it/LC_MESSAGES/django.po
  19. 0 cms/locale/{no → nb}/LC_MESSAGES/django.mo
  20. +1 −1 cms/locale/{no → nb}/LC_MESSAGES/django.po
  21. 0 cms/locale/{no → nb}/LC_MESSAGES/djangojs.mo
  22. +0 −1 cms/locale/{no → nb}/LC_MESSAGES/djangojs.po
  23. +2 −7 cms/management/commands/publisher_publish.py
  24. +18 −4 cms/management/commands/subcommands/moderator.py
  25. +24 −21 cms/menu.py
  26. +10 −2 cms/middleware/toolbar.py
  27. +364 −105 cms/migrations/0001_initial.py
  28. +333 −74 cms/migrations/0002_auto_start.py
  29. +346 −18 cms/migrations/0003_remove_placeholder.py
  30. +333 −80 cms/migrations/0004_textobjects.py
  31. +333 −90 cms/migrations/0005_mptt_added_to_plugins.py
  32. +333 −130 cms/migrations/0006_apphook.py
  33. +333 −76 cms/migrations/0007_apphook_longer.py
  34. +334 −81 cms/migrations/0008_redirects.py
  35. +334 −85 cms/migrations/0009_added_meta_fields.py
  36. +333 −87 cms/migrations/0010_5char_language.py
  37. +332 −86 cms/migrations/0011_title_overwrites.py
  38. +325 −441 cms/migrations/0012_publisher.py
  39. +326 −202 cms/migrations/0013_site_copy.py
  40. +326 −203 cms/migrations/0014_sites_removed.py
  41. +325 −228 cms/migrations/0015_modified_by_added.py
  42. +326 −206 cms/migrations/0016_author_copy.py
  43. +326 −207 cms/migrations/0017_author_removed.py
  44. +326 −208 cms/migrations/0018_site_permissions.py
  45. +326 −214 cms/migrations/0019_public_table_renames.py
  46. +326 −259 cms/migrations/0020_advanced_permissions.py
  47. +314 −384 cms/migrations/0021_publisher2.py
  48. +315 −150 cms/migrations/0022_login_required_added.py
  49. +312 −137 cms/migrations/0023_plugin_table_naming_function_changed.py
  50. +294 −161 cms/migrations/0024_added_placeholder_model.py
  51. +299 −186 cms/migrations/0025_placeholder_migration.py
  52. +296 −152 cms/migrations/0026_finish_placeholder_migration.py
  53. +298 −143 cms/migrations/0027_added_width_to_placeholder.py
  54. +292 −138 cms/migrations/0028_limit_visibility_in_menu_step1of3.py
Sorry, we could not display the entire diff because it was too big.
View
5 AUTHORS
@@ -33,10 +33,12 @@ Contributors (in alphabetical order):
* Andrew Cassidy
* Andrew Schoen
* angular_circle
+* Anton Parkhomenko
* Antoni Aloy López
* Arne Gellhaus
* Artem Skoretskiy
* Arthur Debert
+* Aymeric Augustin
* Batiste Bieler
* behrooz
* Behrooz Nobakht
@@ -68,6 +70,7 @@ Contributors (in alphabetical order):
* eged
* Egor V. Nazarkin
* Ekrem Seren
+* Erlend Dalen
* Eric Eldredge
* Erik Allik
* Eugen MechanisM
@@ -170,6 +173,7 @@ Contributors (in alphabetical order):
* Rebecca Breu
* Remco Wendt
* Restless Being
+* Richard Barran
* Robert Buchholz
* Robert Clark
* Robert Pogorzelski
@@ -204,6 +208,7 @@ Contributors (in alphabetical order):
* tiret
* Ulrich Petri
* Vasil Vangelovski
+* Viliam Segeda
* wangJunjie
* Wayne Moore
* wid
View
12 CHANGELOG.txt
@@ -110,6 +110,14 @@
- fixed an incompatibility with Python 2.5
+==== 2.3.4 (2012-11-09) ====
+
+- Fixed WymEditor
+- Fixed Norwegian translations
+- Fixed a bug that could lead to slug clashes
+- Fixed page change form (jQuery and permissions)
+- Fixed placeholder field permission checks
+
==== 2.4.0 ===-
- CMS_LANGUAGE setting has changed
@@ -122,7 +130,3 @@
- CMS_FLAT_URLS has been removed
-
-
-
-
View
2 cms/__init__.py
@@ -1,5 +1,5 @@
# -*- coding: utf-8 -*-
-__version__ = '2.3.3.post0'
+__version__ = '2.3.4.post0'
# patch settings
try:
View
61 cms/admin/change_list.py
@@ -1,8 +1,7 @@
# -*- coding: utf-8 -*-
+from collections import defaultdict
from cms.exceptions import NoHomeFound
-from cms.models import Title, Page, PageModerator
-from cms.models.moderatormodels import MASK_PAGE, MASK_CHILDREN, \
- MASK_DESCENDANTS, PageModeratorState
+from cms.models import Title, Page, PageModeratorState
from cms.utils.permissions import get_user_sites_queryset
from django.conf import settings
from django.contrib.admin.views.main import ChangeList, ALL_VAR, IS_POPUP_VAR, \
@@ -120,27 +119,7 @@ def set_items(self, request):
if perm_edit_ids and perm_edit_ids != Page.permissions.GRANT_ALL:
pages = pages.filter(pk__in=perm_edit_ids)
#pages = pages.filter(pk__in=perm_change_list_ids)
-
- if settings.CMS_MODERATOR:
- # get all ids of public instances, so we can cache them
- # TODO: add some filtering here, so the set is the same like page set...
- published_public_page_id_set = Page.objects.public().filter(published=True).values_list('id', flat=True)
-
- # get all moderations for current user and all pages
- pages_moderator_set = PageModerator.objects \
- .filter(user=request.user, page__site=self._current_site) \
- .values_list('page', 'moderate_page', 'moderate_children', 'moderate_descendants')
- # put page / moderations into singe dictionary, where key is page.id
- # and value is sum of moderations, so if he can moderate page and descendants
- # value will be MASK_PAGE + MASK_DESCENDANTS
- page_moderator = map(lambda item: (item[0], item[1] * MASK_PAGE + item[2] * MASK_CHILDREN + item[3] * MASK_DESCENDANTS), pages_moderator_set)
- page_moderator = dict(page_moderator)
-
- # page moderator states
- pm_qs = PageModeratorState.objects.filter(page__site=self._current_site)
- pm_qs.query.group_by = ['page_id']
- pagemoderator_states_id_set = pm_qs.values_list('page', flat=True)
-
+
ids = []
root_pages = []
pages = list(pages)
@@ -149,14 +128,22 @@ def set_items(self, request):
home_pk = Page.objects.drafts().get_home(self.current_site()).pk
except NoHomeFound:
home_pk = 0
-
+
+ # page moderator states
+ pm_qs = PageModeratorState.objects.filter(page__in=pages).order_by('page')
+ pm_states = defaultdict(list)
+ for state in pm_qs:
+ pm_states[state.page_id].append(state)
+
+ public_page_id_set = Page.objects.public().filter(
+ published=True, publisher_public__in=pages).values_list('id', flat=True)
+
# Unfortunately we cannot use the MPTT builtin code for pre-caching
# the children here, because MPTT expects the tree to be 'complete'
# and otherwise complaints about 'invalid item order'
cache_tree_children(pages)
for page in pages:
-
children = list(page.get_children())
@@ -176,23 +163,9 @@ def set_items(self, request):
page.permission_publish_cache = perm_publish_ids == Page.permissions.GRANT_ALL or page.pk in perm_publish_ids
page.permission_advanced_settings_cache = perm_advanced_settings_ids == Page.permissions.GRANT_ALL or page.pk in perm_advanced_settings_ids
page.permission_user_cache = request.user
-
- if settings.CMS_MODERATOR:
- # set public instance existence state
- page.public_published_cache = page.publisher_public_id in published_public_page_id_set
-
- # moderation for current user
- moderation_value = 0
- try:
- moderation_value = page_moderator[page.pk]
- except:
- pass
- page._moderation_value_cache = moderation_value
- page._moderation_value_cache_for_user_id = request.user.pk
-
- #moderation states
- page._has_moderator_state_cache = page.pk in pagemoderator_states_id_set
-
+
+ page._moderator_state_cache = pm_states[page.pk]
+ page._public_published_cache = page.publisher_public_id in public_page_id_set
if page.root_node or self.is_filtered():
page.last = True
if len(children):
@@ -222,7 +195,7 @@ def set_items(self, request):
page.childrens = []
else:
page.childrens = children
-
+
# TODO: OPTIMIZE!!
titles = Title.objects.filter(page__in=ids)
for page in all_pages:# add the title and slugs and some meta data
View
13 cms/admin/dialog/forms.py
@@ -9,16 +9,3 @@ class PermissionForm(forms.Form):
copy_permissions = forms.BooleanField(label=_('Copy permissions'),
required=False, initial=True)
-class ModeratorForm(forms.Form):
- '''
- Holds the specific field for moderator
- '''
- copy_moderation = forms.BooleanField(label=_('Copy moderation'),
- required=False, initial=True)
-
-class PermissionAndModeratorForm(PermissionForm, ModeratorForm):
- '''
- Subclass of both ModeratorForm AND PermissionForm, thus it inherits both
- fields
- '''
- pass
View
22 cms/admin/dialog/views.py
@@ -1,40 +1,26 @@
# -*- coding: utf-8 -*-
-from cms.admin.dialog.forms import PermissionAndModeratorForm, PermissionForm, ModeratorForm
+from cms.admin.dialog.forms import PermissionForm
from cms.models import Page
from django.conf import settings
from django.contrib.admin.views.decorators import staff_member_required
from django.http import Http404, HttpResponse
from django.shortcuts import render_to_response, get_object_or_404
-def _form_class_selector():
- '''
- This replaces the magic that used to happen in forms, where a dynamic
- class was generated at runtime. Now it's a bit cleaner...
- '''
- form_class = None
- if settings.CMS_PERMISSION and settings.CMS_MODERATOR:
- form_class = PermissionAndModeratorForm
- elif settings.CMS_PERMISSION:
- form_class = PermissionForm
- elif settings.CMS_MODERATOR:
- form_class = ModeratorForm
- return form_class
-
@staff_member_required
def get_copy_dialog(request, page_id):
- if not (settings.CMS_PERMISSION or settings.CMS_MODERATOR):
+ if not settings.CMS_PERMISSION:
return HttpResponse('')
page = get_object_or_404(Page, pk=page_id)
target = get_object_or_404(Page, pk=request.REQUEST['target'])
if not page.has_change_permission(request) or \
- not target.has_add_permission(request): # pragma: no cover
+ not target.has_add_permission(request):
raise Http404
context = {
'dialog_id': 'dialog-copy',
- 'form': _form_class_selector()(), # class needs to be instanciated
+ 'form': PermissionForm(), # class needs to be instantiated
'callback': request.REQUEST['callback'],
}
return render_to_response("admin/cms/page/dialog/copy.html", context)
View
13 cms/admin/forms.py
@@ -113,7 +113,7 @@ def clean(self):
#AdminFormsTests.test_clean_overwrite_url validates the form with when no page instance available
#Looks like just a theoretical corner case
title = page.get_title_obj(lang)
- if title:
+ if title and slug:
oldslug = title.slug
title.slug = slug
title.save()
@@ -122,8 +122,9 @@ def clean(self):
except ValidationError,e:
title.slug = oldslug
title.save()
- del cleaned_data['published']
- self._errors['published'] = ErrorList(e.messages)
+ if 'slug' in cleaned_data:
+ del cleaned_data['slug']
+ self._errors['slug'] = ErrorList(e.messages)
return cleaned_data
def clean_slug(self):
@@ -149,11 +150,7 @@ class PageForm(PageAddForm):
help_text=_('Hook application to this page.'))
overwrite_url = forms.CharField(label=_('Overwrite URL'), max_length=255, required=False,
help_text=_('Keep this field empty if standard path should be used.'))
- # moderation state
- moderator_state = forms.IntegerField(widget=forms.HiddenInput, required=False, initial=Page.MODERATOR_CHANGED)
- # moderation - message is a fake field
- moderator_message = forms.CharField(max_length=1000, widget=forms.HiddenInput, required=False)
-
+
redirect = forms.CharField(label=_('Redirect'), max_length=255, required=False,
help_text=_('Redirects to this URL.'))
meta_description = forms.CharField(label='Description meta tag', required=False, widget=forms.Textarea,
View
522 cms/admin/pageadmin.py
@@ -1,53 +1,56 @@
# -*- coding: utf-8 -*-
+from copy import deepcopy
+from distutils.version import LooseVersion
+from urllib2 import unquote
+
+import django
+from django.conf import settings
+from django.contrib import admin, messages
+from django.contrib.admin.options import IncorrectLookupParameters
+from django.contrib.admin.util import get_deleted_objects
+from django.contrib.sites.models import Site
+from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ValidationError
+from django.core.urlresolvers import reverse
+from django.db import router, transaction, models
+from django.forms import CharField
+from django.http import (HttpResponseRedirect, HttpResponse, Http404,
+ HttpResponseBadRequest, HttpResponseForbidden)
+from django.shortcuts import render_to_response, get_object_or_404
+from django.template.context import RequestContext
+from django.template.defaultfilters import (title, escape, force_escape, escapejs)
+from django.utils.encoding import force_unicode
+from django.utils.translation import ugettext as _
+from django.utils.decorators import method_decorator
+from django.views.decorators.http import require_POST
+
from cms.admin.change_list import CMSChangeList
from cms.admin.dialog.views import get_copy_dialog
from cms.admin.forms import PageForm, PageAddForm
-from cms.admin.permissionadmin import (PAGE_ADMIN_INLINES,
+from cms.admin.permissionadmin import (PAGE_ADMIN_INLINES,
PagePermissionInlineAdmin, ViewRestrictionInlineAdmin)
from cms.admin.views import revert_plugins
from cms.apphook_pool import apphook_pool
from cms.exceptions import NoPermissionsException
from cms.forms.widgets import PluginEditor
-from cms.models import (Page, Title, CMSPlugin, PagePermission,
+from cms.models import (Page, Title, CMSPlugin, PagePermission,
PageModeratorState, EmptyTitle, GlobalPagePermission)
from cms.models.managers import PagePermissionsPermissionManager
from cms.models.placeholdermodel import Placeholder
from cms.plugin_pool import plugin_pool
from cms.templatetags.cms_admin import admin_static_url
-from cms.utils import (copy_plugins, helpers, moderator, permissions, plugins,
- get_template_from_request, get_language_from_request,
+from cms.utils import (copy_plugins, helpers, moderator, permissions, plugins,
+ get_template_from_request, get_language_from_request,
placeholder as placeholder_utils, admin as admin_utils, cms_static_url)
from cms.utils.i18n import get_language_dict, get_language_list, get_language_tuple, get_language_object
from cms.utils.page_resolver import is_valid_url
from cms.utils.admin import jsonify_request
-from cms.utils.permissions import has_plugin_permission
-from copy import deepcopy
-from distutils.version import LooseVersion
-from django import template
-from django.conf import settings
-from django.contrib import admin
-from django.contrib.admin.options import IncorrectLookupParameters
-from django.contrib.admin.util import get_deleted_objects
-from urllib2 import unquote
-from django.contrib.sites.models import Site
-from django.core.exceptions import PermissionDenied, ObjectDoesNotExist, ValidationError
-from django.core.urlresolvers import reverse
-from django.db import router, transaction, models
-from django.forms import CharField
-from django.http import (HttpResponseRedirect, HttpResponse, Http404,
- HttpResponseBadRequest, HttpResponseForbidden, HttpResponseNotAllowed, HttpResponseServerError)
-from django.shortcuts import render_to_response, get_object_or_404
-from django.template.context import RequestContext
-from django.template.defaultfilters import (title, escape, force_escape,
- escapejs)
-from django.utils.encoding import force_unicode
-from django.utils.translation import ugettext, ugettext_lazy as _
-from menus.menu_pool import menu_pool
-import django
+from cms.utils.permissions import has_global_page_permission
+from cms.utils.plugins import current_site
+from menus.menu_pool import menu_pool
DJANGO_1_3 = LooseVersion(django.get_version()) < LooseVersion('1.4')
-
+require_POST = method_decorator(require_POST)
if 'reversion' in settings.INSTALLED_APPS:
import reversion
@@ -64,7 +67,7 @@
class ModelAdmin(ModelAdmin):
def get_inline_instances(self, request):
return self.inline_instances
-
+
def get_prepopulated_fields(self, request):
return self.prepopulated_fields
@@ -76,7 +79,7 @@ def contribute_fieldsets(cls):
general_fields = ['title']
general_fields += ['slug', ('published', 'in_navigation')]
additional_hidden_fields = []
- advanced_fields = ['reverse_id', 'overwrite_url', 'redirect', 'login_required', 'limit_visibility_in_menu']
+ advanced_fields = ['reverse_id', 'overwrite_url', 'redirect', 'login_required', 'limit_visibility_in_menu']
template_fields = ['template']
hidden_fields = ['site', 'parent']
seo_fields = []
@@ -87,9 +90,7 @@ def contribute_fieldsets(cls):
elif settings.CMS_SHOW_START_DATE:
general_fields.append('publication_date')
elif settings.CMS_SHOW_END_DATE:
- general_fields.append( 'publication_end_date')
- if settings.CMS_MODERATOR:
- additional_hidden_fields += ['moderator_state', 'moderator_message']
+ general_fields.append('publication_end_date')
if settings.CMS_SEO_FIELDS:
seo_fields = ['page_title', 'meta_description', 'meta_keywords']
if not settings.CMS_URL_OVERWRITE:
@@ -137,8 +138,6 @@ def contribute_fieldsets(cls):
def contribute_list_filter(cls):
list_filter = ['published', 'in_navigation', 'template', 'changed_by']
- if settings.CMS_MODERATOR:
- list_filter.append('moderator_state')
if settings.CMS_SOFTROOT:
list_filter.append('soft_root')
setattr(cls, 'list_filter', list_filter)
@@ -210,25 +209,25 @@ def get_urls(self):
pat(r'^([0-9]+)/jsi18n/$', self.redirect_jsi18n),
pat(r'^([0-9]+)/permissions/$', self.get_permissions),
pat(r'^([0-9]+)/moderation-states/$', self.get_moderation_states),
- pat(r'^([0-9]+)/change-moderation/$', self.change_moderation),
- pat(r'^([0-9]+)/approve/$', self.approve_page), # approve page
pat(r'^([0-9]+)/publish/$', self.publish_page), # publish page
+ pat(r'^([0-9]+)/revert/$', self.revert_page), # publish page
+ pat(r'^([0-9]+)/confirm-delete/$', self.confirm_delete),
pat(r'^([0-9]+)/remove-delete-state/$', self.remove_delete_state),
pat(r'^([0-9]+)/dialog/copy/$', get_copy_dialog), # copy dialog
pat(r'^([0-9]+)/preview/$', self.preview_page), # copy dialog
pat(r'^([0-9]+)/descendants/$', self.descendants), # menu html for page descendants
pat(r'^(?P<object_id>\d+)/change_template/$', self.change_template), # copy dialog
)
- url_patterns = url_patterns + super(PageAdmin, self).get_urls()
+ url_patterns += super(PageAdmin, self).get_urls()
return url_patterns
def redirect_jsi18n(self, request):
return HttpResponseRedirect(reverse('admin:jsi18n'))
def save_model(self, request, obj, form, change):
"""
- Move the page in the tree if neccesary and save every placeholder
+ Move the page in the tree if necessary and save every placeholder
Content object.
"""
target = request.GET.get('target', None)
@@ -248,8 +247,7 @@ def save_model(self, request, obj, form, change):
obj.insert_at(parent, save=False)
obj.pk = pk
obj.save(no_signals=True)
- obj.save()
-
+
else:
if 'history' in request.path:
old_obj = Page.objects.get(pk=obj.pk)
@@ -258,18 +256,14 @@ def save_model(self, request, obj, form, change):
obj.rght = old_obj.rght
obj.lft = old_obj.lft
obj.tree_id = old_obj.tree_id
- force_with_moderation = target is not None and position is not None and \
- moderator.will_require_moderation(target, position)
- obj.save(force_with_moderation=force_with_moderation)
+ obj.save()
if 'recover' in request.path or 'history' in request.path:
obj.pagemoderatorstate_set.all().delete()
- if settings.CMS_MODERATOR:
- from cms.utils.moderator import page_changed
- page_changed(obj, force_moderation_action=PageModeratorState.ACTION_CHANGED)
+ moderator.page_changed(obj, force_moderation_action=PageModeratorState.ACTION_CHANGED)
revert_plugins(request, obj.version.pk, obj)
-
+
language = form.cleaned_data['language']
if target is not None and position is not None:
@@ -287,30 +281,9 @@ def save_model(self, request, obj, form, change):
language,
)
- # is there any moderation message? save/update state
- if settings.CMS_MODERATOR and 'moderator_message' in form.cleaned_data and \
- form.cleaned_data['moderator_message']:
- moderator.update_moderation_message(obj, form.cleaned_data['moderator_message'])
-
if obj and "reversion" in settings.INSTALLED_APPS:
helpers.make_revision_with_plugins(obj)
- @create_on_success
- def change_template(self, request, object_id):
- page = get_object_or_404(Page, pk=object_id)
- if page.has_change_permission(request):
- to_template = request.POST.get("template", None)
- if to_template in dict(settings.CMS_TEMPLATES):
- page.template = to_template
- page.save()
- if "reversion" in settings.INSTALLED_APPS:
- helpers.make_revision_with_plugins(page)
- return HttpResponse(str("ok"))
- else:
- return HttpResponseBadRequest("template not valid")
- else:
- return HttpResponseForbidden(_("You have no permission to change the template"))
-
def get_fieldsets(self, request, obj=None):
"""
Add fieldsets of placeholders to the list of already existing
@@ -337,7 +310,7 @@ def get_fieldsets(self, request, obj=None):
given_fieldsets = deepcopy(self.add_fieldsets)
return given_fieldsets
-
+
def get_fieldset_placeholders(self, template):
return plugins.get_placeholders(template)
@@ -365,11 +338,7 @@ def get_form(self, request, obj=None, **kwargs):
if "history" in request.path or 'recover' in request.path:
versioned = True
version_id = request.path.split("/")[-2]
- else:
- self.inlines = []
- form = PageAddForm
- if obj:
try:
title_obj = obj.get_title_obj(language=language, fallback=False, version_id=version_id, force_reload=True)
except:
@@ -459,15 +428,19 @@ def get_form(self, request, obj=None, **kwargs):
'placeholder': placeholder
})
form.base_fields[placeholder.slot] = CharField(widget=widget, required=False)
+
+ if not obj.has_advanced_settings_permission(request):
+ for field in self.advanced_fields:
+ del form.base_fields[field]
else:
+ self.inlines = []
+ form = PageAddForm
for name in ['slug','title']:
form.base_fields[name].initial = u''
form.base_fields['parent'].initial = request.GET.get('target', None)
form.base_fields['site'].initial = request.session.get('cms_admin_site', None)
form.base_fields['template'].initial = settings.CMS_TEMPLATES[0][0]
- if obj and not obj.has_advanced_settings_permission(request):
- for field in self.advanced_fields:
- del form.base_fields[field]
+
return form
# remove permission inlines, if user isn't allowed to change them
@@ -490,15 +463,6 @@ def get_formsets(self, request, obj=None):
def add_view(self, request, form_url='', extra_context=None):
extra_context = extra_context or {}
- if settings.CMS_MODERATOR and 'target' in request.GET and 'position' in request.GET:
- moderation_required = moderator.will_require_moderation(
- request.GET['target'], request.GET['position']
- )
- extra_context.update({
- 'moderation_required': moderation_required,
- 'moderation_level': _('higher'),
- 'show_save_and_continue':True,
- })
language = get_language_from_request(request)
extra_context.update({
'language': language,
@@ -518,27 +482,17 @@ def change_view(self, request, object_id, extra_context=None):
obj = None
else:
selected_template = get_template_from_request(request, obj)
- moderation_level, moderation_required = moderator.get_test_moderation_level(obj, request.user)
-
- # if there is a delete request for this page
- moderation_delete_request = (settings.CMS_MODERATOR and
- obj.pagemoderatorstate_set.get_delete_actions(
- ).count())
-
#activate(user_lang_set)
context = {
'placeholders': self.get_fieldset_placeholders(selected_template),
'page': obj,
'CMS_PERMISSION': settings.CMS_PERMISSION,
- 'CMS_MODERATOR': settings.CMS_MODERATOR,
'ADMIN_MEDIA_URL': settings.STATIC_URL,
- 'has_change_permissions_permission': obj.has_change_permissions_permission(request),
- 'has_moderate_permission': obj.has_moderate_permission(request),
- 'moderation_level': moderation_level,
- 'moderation_required': moderation_required,
- 'moderator_should_approve': moderator.moderator_should_approve(request, obj),
- 'moderation_delete_request': moderation_delete_request,
+ 'can_change': obj.has_change_permission(request),
+ 'can_change_permissions': obj.has_change_permissions_permission(request),
+ 'can_publish': obj.has_publish_permission(request),
+ 'delete_requested': obj.delete_requested(),
'show_delete_translation': len(obj.get_languages()) > 1,
'current_site_id': settings.SITE_ID,
}
@@ -562,7 +516,7 @@ def render_change_form(self, request, context, add=False, change=False, form_url
'filled_languages': [lang for lang in filled_languages if lang in allowed_languages],
})
return super(PageAdmin, self).render_change_form(request, context, add, change, form_url, obj)
-
+
def _get_site_languages(self, obj):
site_id = None
if obj:
@@ -586,10 +540,9 @@ def response_change(self, request, obj):
some new stuff, which should be published after all other objects on page
are collected.
"""
- if settings.CMS_MODERATOR:
- # save the object again, so all the related changes to page model
- # can be published if required
- obj.save()
+ # save the object again, so all the related changes to page model
+ # can be published if required
+ obj.save()
return super(PageAdmin, self).response_change(request, obj)
def has_add_permission(self, request):
@@ -632,8 +585,7 @@ def has_recover_permission(self, request):
if user.is_superuser:
return True
try:
- perm = GlobalPagePermission.objects.get(user=user)
- if perm.can_recover:
+ if has_global_page_permission(request, can_recover_page=True):
return True
except:
pass
@@ -645,7 +597,7 @@ def changelist_view(self, request, extra_context=None):
opts = self.model._meta
app_label = opts.app_label
if not self.has_change_permission(request, None):
- raise PermissionDenied
+ return HttpResponseForbidden(_("You do not have permission to change pages."))
try:
if DJANGO_1_3:
cl = CMSChangeList(request, self.model, self.list_display, self.list_display_links, self.list_filter,
@@ -663,12 +615,12 @@ def changelist_view(self, request, extra_context=None):
return render_to_response('admin/invalid_setup.html', {'title': _('Database error')})
return HttpResponseRedirect(request.path + '?' + ERROR_FLAG + '=1')
cl.set_items(request)
-
+
site_id = request.GET.get('site__exact', None)
if site_id is None:
- site_id = Site.objects.get_current().pk
+ site_id = current_site(request).pk
site_id = int(site_id)
-
+
# languages
languages = get_language_list(site_id)
@@ -689,15 +641,15 @@ def changelist_view(self, request, extra_context=None):
'root_path': reverse('admin:index'),
'app_label': app_label,
'CMS_MEDIA_URL': settings.CMS_MEDIA_URL,
+ 'CMS_SHOW_END_DATE': settings.CMS_SHOW_END_DATE,
'softroot': settings.CMS_SOFTROOT,
'CMS_PERMISSION': settings.CMS_PERMISSION,
- 'CMS_MODERATOR': settings.CMS_MODERATOR,
- 'has_recover_permission': 'reversion' in settings.INSTALLED_APPS and self.has_recover_permission(request),
'DEBUG': settings.DEBUG,
'site_languages': languages,
'open_menu_trees': open_menu_trees,
}
if 'reversion' in settings.INSTALLED_APPS:
+ context['has_recover_permission'] = self.has_recover_permission(request)
context['has_change_permission'] = self.has_change_permission(request)
context.update(extra_context or {})
return render_to_response(self.change_list_template or [
@@ -743,11 +695,28 @@ def render_revision_form(self, request, obj, version, context, revert=False, rec
obj.parent = None
obj.parent_id = None
version.field_dict['parent'] = None
-
+
obj.version = version
return super(PageAdmin, self).render_revision_form(request, obj, version, context, revert, recover)
+ @require_POST
+ @create_on_success
+ def change_template(self, request, object_id):
+ page = get_object_or_404(Page, pk=object_id)
+ if not page.has_change_permission(request):
+ return HttpResponseForbidden(_("You do not have permission to change the template"))
+
+ to_template = request.POST.get("template", None)
+ if to_template not in dict(settings.CMS_TEMPLATES):
+ return HttpResponseBadRequest(_("Template not valid"))
+
+ page.template = to_template
+ page.save()
+ if "reversion" in settings.INSTALLED_APPS:
+ helpers.make_revision_with_plugins(page)
+ return HttpResponse(_("The template was successfully changed"))
+
@transaction.commit_on_success
def move_page(self, request, page_id, extra_context=None):
"""
@@ -769,9 +738,12 @@ def move_page(self, request, page_id, extra_context=None):
not target.has_add_permission(request):
return jsonify_request(HttpResponseForbidden(_("Error! You don't have permissions to move this page. Please reload the page")))
+ if page.delete_requested():
+ return jsonify_request(HttpResponseBadRequest(_('The page "%s" has a delete request. Delete or confirm the request first.') % page))
+
# move page
page.move_page(target, position)
-
+
if "reversion" in settings.INSTALLED_APPS:
helpers.make_revision_with_plugins(page)
@@ -787,7 +759,7 @@ def get_permissions(self, request, page_id):
all_permissions = list(global_page_permissions) + list(page_permissions)
# does he can change global permissions ?
- has_global = permissions.has_global_change_permissions_permission(request.user)
+ has_global = permissions.has_global_change_permissions_permission(request)
permission_set = []
for permission in all_permissions:
@@ -833,89 +805,123 @@ def copy_page(self, request, page_id, extra_context=None):
try:
kwargs = {
'copy_permissions': request.REQUEST.get('copy_permissions', False),
- 'copy_moderation': request.REQUEST.get('copy_moderation', False),
}
page.copy_page(target, site, position, **kwargs)
return jsonify_request(HttpResponse("ok"))
- except ValidationError,e:
+ except ValidationError, e:
return jsonify_request(HttpResponseBadRequest(e.messages))
context.update(extra_context or {})
return HttpResponseRedirect('../../')
def get_moderation_states(self, request, page_id):
- """Returns moderation messsages. Is loaded over ajax to inline-group
+ """Returns moderation messages. Is loaded over ajax to inline-group
element in change form view.
"""
page = get_object_or_404(Page, id=page_id)
- if not page.has_moderate_permission(request):
- raise Http404()
-
context = {
'page': page,
}
return render_to_response('admin/cms/page/moderation_messages.html', context)
+ #TODO: Make the change form buttons use POST
+ #@require_POST
@transaction.commit_on_success
- def approve_page(self, request, page_id):
- """Approve changes on current page by user from request.
- """
- #TODO: change to POST method !! get is not safe
+ def publish_page(self, request, page_id):
page = get_object_or_404(Page, id=page_id)
- if not page.has_moderate_permission(request):
- raise Http404()
+ # ensure user has permissions to publish this page
+ if not page.has_publish_permission(request):
+ return HttpResponseForbidden(_("You do not have permission to publish this page"))
- moderator.approve_page(request, page)
+ if page.delete_requested():
+ messages.error(request, _('The page "%s" has a delete request. Delete or confirm the request first.') % page)
+ else:
+ page.publish()
- # Django SQLite bug. Does not convert to string the lazy instances
- from django.utils.translation import ugettext as _
- self.message_user(request, _('Page was successfully approved.'))
+ messages.info(request, _('The page "%s" was successfully published.') % page)
if 'node' in request.REQUEST:
# if request comes from tree..
return admin_utils.render_admin_menu_item(request, page)
- referer = request.META.get('HTTP_REFERER', reverse('admin:cms_page_changelist'))
+
+ referer = request.META.get('HTTP_REFERER', '')
path = '../../'
+ # TODO: use admin base here!
if 'admin' not in referer:
path = '%s?edit-off' % referer.split('?')[0]
- return HttpResponseRedirect( path )
-
+ return HttpResponseRedirect(path)
+ #TODO: Make the change form buttons use POST
+ #@require_POST
@transaction.commit_on_success
- def publish_page(self, request, page_id):
+ def revert_page(self, request, page_id):
page = get_object_or_404(Page, id=page_id)
# ensure user has permissions to publish this page
- if not page.has_moderate_permission(request):
- return HttpResponseForbidden("Denied")
- page.publish()
+ if not page.has_change_permission(request):
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
+
+ page.revert()
+
+ messages.info(request, _('The page "%s" was successfully reverted.') % page)
+
+ if 'node' in request.REQUEST:
+ # if request comes from tree..
+ return admin_utils.render_admin_menu_item(request, page)
+
referer = request.META.get('HTTP_REFERER', '')
path = '../../'
# TODO: use admin base here!
if 'admin' not in referer:
path = '%s?edit-off' % referer.split('?')[0]
- return HttpResponseRedirect( path )
+ return HttpResponseRedirect(path)
+ #TODO: Make the change form buttons use POST
+ #@require_POST
+ def confirm_delete(self, request, object_id, *args, **kwargs):
+ """Remove all delete action from page states, requires change permission
+ """
+ page = get_object_or_404(Page, id=object_id)
+ if not page.has_publish_permission(request):
+ return HttpResponseForbidden(_("You do not have permission to publish this page"))
+
+ page_title = unicode(page)
+ if not page.delete_requested():
+ messages.error(request, _('The page "%s" has no delete request.') % page_title)
+ else:
+ try:
+ page.delete_with_public()
+ messages.info(request, _('The page "%s" was successfully deleted.') % page_title)
+ return HttpResponseRedirect("../../")
+ except PermissionDenied, e:
+ messages.error(request, e.message)
+ return HttpResponseRedirect("../")
+
+ #TODO: Make the change form buttons use POST
+ #@require_POST
+ def remove_delete_state(self, request, object_id):
+ """Remove all delete action from page states, requires change permission
+ """
+ page = get_object_or_404(Page, id=object_id)
+ if not self.has_change_permission(request, page):
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
+ page.pagemoderatorstate_set.get_delete_actions().delete()
+ page.save()
+ return HttpResponseRedirect("../../%d/" % page.id)
def delete_view(self, request, object_id, *args, **kwargs):
- """If page is under modaretion, just mark this page for deletion = add
+ """If page is under moderation, just mark this page for deletion = add
delete action to page states.
"""
page = get_object_or_404(Page, id=object_id)
if not self.has_delete_permission(request, page):
- raise PermissionDenied
-
- if settings.CMS_MODERATOR and page.is_under_moderation():
- # don't perform a delete action, just mark page for deletion
- page.force_moderation_action = PageModeratorState.ACTION_DELETE
- page.moderator_state = Page.MODERATOR_NEED_DELETE_APPROVEMENT
- page.save()
+ return HttpResponseForbidden(_("You do not have permission to delete this page"))
- if not self.has_change_permission(request, None):
- return HttpResponseRedirect("../../../../")
- return HttpResponseRedirect("../../")
+ # don't perform a delete action, just mark page for deletion
+ moderator.page_changed(page, force_moderation_action=PageModeratorState.ACTION_DELETE)
- response = super(PageAdmin, self).delete_view(request, object_id, *args, **kwargs)
- return response
+ if not self.has_change_permission(request, None):
+ return HttpResponseRedirect("../../../../")
+ return HttpResponseRedirect("../../")
@create_on_success
def delete_translation(self, request, object_id, extra_context=None):
@@ -936,7 +942,7 @@ def delete_translation(self, request, object_id, extra_context=None):
obj = None
if not self.has_delete_permission(request, obj):
- raise PermissionDenied
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
if obj is None:
raise Http404(
@@ -950,14 +956,14 @@ def delete_translation(self, request, object_id, extra_context=None):
titleobj = get_object_or_404(Title, page__id=object_id, language=language)
saved_plugins = CMSPlugin.objects.filter(placeholder__page__id=object_id, language=language)
-
+
using = router.db_for_read(self.model)
kwargs = {
'admin_site': self.admin_site,
'user': request.user,
'using': using
}
- deleted_objects, perms_needed = get_deleted_objects(
+ deleted_objects, perms_needed = get_deleted_objects(
[titleobj],
titleopts,
**kwargs
@@ -969,7 +975,7 @@ def delete_translation(self, request, object_id, extra_context=None):
)[:2]
deleted_objects.append(to_delete_plugins)
- perms_needed = set( list(perms_needed) + list(perms_needed_plugins) )
+ perms_needed = set(list(perms_needed) + list(perms_needed_plugins))
if request.method == 'POST':
if perms_needed:
@@ -979,7 +985,7 @@ def delete_translation(self, request, object_id, extra_context=None):
'language': get_language_object(language)['name']
}
self.log_change(request, titleobj, message)
- self.message_user(request, message)
+ messages.info(request, message)
titleobj.delete()
for p in saved_plugins:
@@ -988,10 +994,10 @@ def delete_translation(self, request, object_id, extra_context=None):
public = obj.publisher_public
if public:
public.save()
-
+
if "reversion" in settings.INSTALLED_APPS:
helpers.make_revision_with_plugins(obj)
-
+
if not self.has_change_permission(request, None):
return HttpResponseRedirect("../../../../")
return HttpResponseRedirect("../../")
@@ -1014,67 +1020,64 @@ def delete_translation(self, request, object_id, extra_context=None):
"admin/delete_confirmation.html"
], context, context_instance=context_instance)
- def remove_delete_state(self, request, object_id):
- """Remove all delete action from page states, requires change permission
- """
- page = get_object_or_404(Page, id=object_id)
- if not self.has_change_permission(request, page):
- raise PermissionDenied
- page.pagemoderatorstate_set.get_delete_actions().delete()
- page.moderator_state = Page.MODERATOR_NEED_APPROVEMENT
- page.save()
- return HttpResponseRedirect("../../%d/" % page.id)
-
def preview_page(self, request, object_id):
"""Redirecting preview function based on draft_id
"""
page = get_object_or_404(Page, id=object_id)
attrs = "?preview=1"
if request.REQUEST.get('public', None):
if not page.publisher_public_id:
- raise Http404
+ raise Http404()
page = page.publisher_public
else:
attrs += "&draft=1"
+ language = request.REQUEST.get('language', None)
+ if language:
+ attrs += "&language=" + language
- url = page.get_absolute_url() + attrs
-
- site = Site.objects.get_current()
+ url = page.get_absolute_url(language) + attrs
+ site = current_site(request)
if not site == page.site:
url = "http%s://%s%s" % ('s' if request.is_secure() else '',
page.site.domain, url)
return HttpResponseRedirect(url)
+ @require_POST
def change_status(self, request, page_id):
"""
Switch the status of a page
"""
- if request.method != 'POST':
- return HttpResponseNotAllowed(['POST'])
page = get_object_or_404(Page, pk=page_id)
- if page.has_publish_permission(request):
- try:
- if page.published or is_valid_url(page.get_absolute_url(),page,False):
- page.published = not page.published
- page.save()
- return jsonify_request(HttpResponse(admin_utils.render_admin_menu_item(request, page).content))
- except ValidationError,e:
- return jsonify_request(HttpResponseBadRequest(e.messages))
- else:
- return HttpResponseForbidden(unicode(_("You do not have permission to publish this page")))
+ if not page.has_publish_permission(request):
+ return HttpResponseForbidden(_("You do not have permission to publish this page"))
+
+ try:
+ if page.published or is_valid_url(page.get_absolute_url(),page,False):
+ published = page.published
+ method = page.publish if not published else page.unpublish
+ try:
+ success = method()
+ if published:
+ messages.info(request, _('The page "%s" was successfully unpublished') % page)
+ else:
+ messages.info(request, _('The page "%s" was successfully published') % page)
+ except RuntimeError, e:
+ messages.error(request, e.message)
+ return admin_utils.render_admin_menu_item(request, page)
+ except ValidationError, e:
+ return HttpResponseBadRequest(e.messages)
+ @require_POST
def change_innavigation(self, request, page_id):
"""
Switch the in_navigation of a page
"""
# why require post and still have page id in the URL???
- if request.method != 'POST':
- return HttpResponseNotAllowed(['POST'])
page = get_object_or_404(Page, pk=page_id)
if page.has_change_permission(request):
page.in_navigation = not page.in_navigation
- page.save(force_state=Page.MODERATOR_NEED_APPROVEMENT)
+ page.save()
return admin_utils.render_admin_menu_item(request, page)
return HttpResponseForbidden(_("You do not have permission to change this page's in_navigation status"))
@@ -1089,19 +1092,18 @@ def descendants(self, request, page_id):
page = get_object_or_404(Page, pk=page_id)
return admin_utils.render_admin_menu_item(request, page,
template="admin/cms/page/lazy_menu.html")
-
+
+ @require_POST
@create_on_success
def add_plugin(self, request):
- '''
+ """
Could be either a page or a parent - if it's a parent we get the page via parent.
- '''
+ """
if 'history' in request.path or 'recover' in request.path:
- return HttpResponse(str("error"))
- if request.method != "POST":
- raise Http404
+ return HttpResponseBadRequest(str("error"))
plugin_type = request.POST['plugin_type']
if not permissions.has_plugin_permission(request.user, plugin_type, "add"):
- return HttpResponseForbidden(ugettext('You have no permission to add a plugin'))
+ return HttpResponseForbidden(_('You do not have permission to add a plugin'))
placeholder_id = request.POST.get('placeholder', None)
parent_id = request.POST.get('parent_id', None)
if placeholder_id:
@@ -1120,83 +1122,84 @@ def add_plugin(self, request):
global_limit = limits.get("global")
type_limit = limits.get(plugin_type)
if global_limit and position >= global_limit:
- return HttpResponseBadRequest("This placeholder already has the maximum number of plugins")
+ return HttpResponseBadRequest(_("This placeholder already has the maximum number of plugins"))
elif type_limit:
type_count = CMSPlugin.objects.filter(language=language, placeholder=placeholder, plugin_type=plugin_type).count()
if type_count >= type_limit:
plugin_name = unicode(plugin_pool.get_plugin(plugin_type).name)
- return HttpResponseBadRequest("This placeholder already has the maximum number allowed of %s plugins." % plugin_name)
+ return HttpResponseBadRequest(_("This placeholder already has the maximum number allowed of %s plugins.") % plugin_name)
# in-plugin add-plugin
elif parent_id:
parent = get_object_or_404(CMSPlugin, pk=parent_id)
placeholder = parent.placeholder
page = placeholder.page if placeholder else None
if not page: # Make sure we do have a page
- raise Http404
+ raise Http404()
language = parent.language
position = None
# placeholder (non-page) add-plugin
else:
# do NOT allow non-page placeholders to use this method, they
# should use their respective admin!
- raise Http404
+ raise Http404()
if not page.has_change_permission(request):
# we raise a 404 instead of 403 for a slightly improved security
# and to be consistent with placeholder admin
- raise Http404
+ raise Http404()
# Sanity check to make sure we're not getting bogus values from JavaScript:
if not language or not language in [ lang[0] for lang in settings.LANGUAGES ]:
- return HttpResponseBadRequest(ugettext("Language must be set to a supported language!"))
+ return HttpResponseBadRequest(_("Language must be set to a supported language!"))
plugin = CMSPlugin(language=language, plugin_type=plugin_type, position=position, placeholder=placeholder)
if parent:
plugin.parent = parent
+ plugin.position = CMSPlugin.objects.filter(parent=parent).count()
plugin.save()
if 'reversion' in settings.INSTALLED_APPS and page:
helpers.make_revision_with_plugins(page)
reversion.revision.user = request.user
plugin_name = unicode(plugin_pool.get_plugin(plugin_type).name)
- reversion.revision.comment = unicode(_(u"%(plugin_name)s plugin added to %(placeholder)s") % {'plugin_name':plugin_name, 'placeholder':placeholder})
+ reversion.revision.comment = _(u"%(plugin_name)s plugin added to %(placeholder)s") % {
+ 'plugin_name': plugin_name, 'placeholder': placeholder}
return HttpResponse(str(plugin.pk))
+ @require_POST
@create_on_success
@transaction.commit_on_success
def copy_plugins(self, request):
if 'history' in request.path or 'recover' in request.path:
- return HttpResponse(str("error"))
- if request.method != "POST":
- raise Http404
+ return HttpResponseBadRequest(str("error"))
copy_from = request.POST['copy_from']
placeholder_id = request.POST['placeholder']
placeholder = get_object_or_404(Placeholder, pk=placeholder_id)
page = placeholder.page
language = request.POST['language'] or get_language_from_request(request)
if not page.has_change_permission(request):
- return HttpResponseForbidden(ugettext("You do not have permission to change this page"))
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
if not language or not language in get_language_list():
- return HttpResponseBadRequest(ugettext("Language must be set to a supported language!"))
+ return HttpResponseBadRequest(_("Language must be set to a supported language!"))
if language == copy_from:
- return HttpResponseBadRequest(ugettext("Language must be different than the copied language!"))
+ return HttpResponseBadRequest(_("Language must be different than the copied language!"))
plugins = list(placeholder.cmsplugin_set.filter(language=copy_from).order_by('tree_id', '-rght'))
# check permissions before copy the plugins:
for plugin in plugins:
if not permissions.has_plugin_permission(request.user, plugin.plugin_type, "add"):
- return HttpResponseForbidden(ugettext("You do not have permission to add plugins"))
+ return HttpResponseForbidden(_("You do not have permission to add plugins"))
copy_plugins.copy_plugins_to(plugins, placeholder, language)
if page and "reversion" in settings.INSTALLED_APPS:
helpers.make_revision_with_plugins(page)
reversion.revision.user = request.user
- reversion.revision.comment = _(u"Copied %(language)s plugins to %(placeholder)s") % {'language': ugettext(dict(settings.LANGUAGES)[language]),
- 'placeholder': placeholder}
+ reversion.revision.comment = _(u"Copied %(language)s plugins to %(placeholder)s") % {
+ 'language': _(dict(settings.LANGUAGES)[language]), 'placeholder': placeholder}
plugin_list = CMSPlugin.objects.filter(language=language, placeholder=placeholder, parent=None).order_by('position')
return render_to_response('admin/cms/page/widgets/plugin_item.html', {'plugin_list':plugin_list}, RequestContext(request))
@@ -1209,7 +1212,7 @@ def edit_plugin(self, request, plugin_id):
page = cms_plugin.placeholder.page if cms_plugin.placeholder else None
instance, plugin_admin = cms_plugin.get_plugin_instance(self.admin_site)
if page and not page.has_change_permission(request):
- return HttpResponseForbidden(ugettext("You have no permission to change this page"))
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
else:
# history view with reversion
from reversion.models import Version
@@ -1240,10 +1243,10 @@ def edit_plugin(self, request, plugin_id):
instance = obj
break
if not instance:
- raise Http404("This plugin is not saved in a revision")
+ raise Http404(_("This plugin is not saved in a revision"))
if not permissions.has_plugin_permission(request.user, cms_plugin.plugin_type, "change"):
- return HttpResponseForbidden(ugettext("You have no permission to edit a plugin"))
+ return HttpResponseForbidden(_("You do not have permission to edit a plugin"))
plugin_admin.cms_plugin_instance = cms_plugin
try:
@@ -1293,13 +1296,15 @@ def edit_plugin(self, request, plugin_id):
# just pass id to plugin_admin
response = plugin_admin.change_view(request, str(plugin_id))
if request.method == "POST" and plugin_admin.object_successfully_changed:
-
+ moderator.page_changed(page,
+ force_moderation_action=PageModeratorState.ACTION_CHANGED)
+
# if reversion is installed, save version of the page plugins
if 'reversion' in settings.INSTALLED_APPS and page:
- helpers.make_revision_with_plugins(page)
+ helpers.make_revision_with_plugins(page)
reversion.revision.user = request.user
plugin_name = unicode(plugin_pool.get_plugin(cms_plugin.plugin_type).name)
- reversion.revision.comment = ugettext(u"%(plugin_name)s plugin edited at position %(position)s in %(placeholder)s") % {
+ reversion.revision.comment = _(u"%(plugin_name)s plugin edited at position %(position)s in %(placeholder)s") % {
'plugin_name': plugin_name,
'position': cms_plugin.position,
'placeholder': cms_plugin.placeholder.slot
@@ -1321,28 +1326,27 @@ def edit_plugin(self, request, plugin_id):
return response
+ @require_POST
@create_on_success
def move_plugin(self, request):
- if request.method != "POST":
- return HttpResponse(str("error"))
if 'history' in request.path:
- return HttpResponse(str("error"))
+ return HttpResponseBadRequest(str("error"))
pos = 0
page = None
success = False
if 'plugin_id' in request.POST:
plugin = CMSPlugin.objects.get(pk=int(request.POST['plugin_id']))
if not permissions.has_plugin_permission(request.user, plugin.plugin_type, "change"):
- return HttpResponseForbidden()
+ return HttpResponseForbidden(_('You do not have permission to edit a plugin'))
page = plugins.get_page_from_plugin_or_404(plugin)
if not page.has_change_permission(request):
- return HttpResponseForbidden(ugettext("You have no permission to change this page"))
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
placeholder_slot = request.POST['placeholder']
placeholders = self.get_fieldset_placeholders(page.get_template())
if not placeholder_slot in placeholders:
- return HttpResponse(str("error"))
+ return HttpResponseBadRequest(str("error"))
placeholder = page.placeholders.get(slot=placeholder_slot)
plugin.placeholder = placeholder
# plugin positions are 0 based, so just using count here should give us 'last_position + 1'
@@ -1358,12 +1362,12 @@ def move_plugin(self, request):
for plugin_id in request.POST['ids'].split("_"):
plugin = CMSPlugin.objects.select_related('placeholder').get(pk=plugin_id)
if not permissions.has_plugin_permission(request.user, plugin.plugin_type, "change"):
- return HttpResponseForbidden(ugettext("You have no permission to move a plugin"))
+ return HttpResponseForbidden(_("You do not have permission to move a plugin"))
page = plugin.placeholder.page if plugin.placeholder else None
if not page: # use placeholderadmin instead!
- raise Http404
+ raise Http404()
if not page.has_change_permission(request):
- return HttpResponseForbidden(ugettext("You have no permission to change this page"))
+ return HttpResponseForbidden(_("You do not have permission to change this page"))
if plugin.position != pos:
plugin.position = pos
@@ -1373,84 +1377,60 @@ def move_plugin(self, request):
if not success:
return HttpResponse(str("error"))
+ moderator.page_changed(page,
+ force_moderation_action=PageModeratorState.ACTION_CHANGED)
+
if page and 'reversion' in settings.INSTALLED_APPS:
helpers.make_revision_with_plugins(page)
reversion.revision.user = request.user
- reversion.revision.comment = ugettext(u"Plugins where moved")
+ reversion.revision.comment = _(u"Plugins were moved")
return HttpResponse(str("ok"))
+ @require_POST
@create_on_success
def remove_plugin(self, request):
- if request.method != "POST":
- raise Http404
if 'history' in request.path:
- raise Http404
+ raise Http404()
plugin_id = request.POST['plugin_id']
plugin = get_object_or_404(CMSPlugin.objects.select_related('placeholder'), pk=plugin_id)
if not permissions.has_plugin_permission(request.user, plugin.plugin_type, "delete"):
- return HttpResponseForbidden(ugettext("You have no permission to remove a plugin"))
+ return HttpResponseForbidden(_("You do not have permission to remove a plugin"))
placeholder = plugin.placeholder
page = placeholder.page if placeholder else None
- if page and not page.has_change_permission(request):
- raise Http404
+ if page:
+ if not page.publisher_is_draft:
+ raise Http404()
+ if not page.has_change_permission(request):
+ return HttpResponseForbidden(_("You do not have permission to remove a plugin"))
- if page and settings.CMS_MODERATOR and page.is_under_moderation():
# delete the draft version of the plugin
plugin.delete()
# set the page to require approval and save
- page.moderator_state = Page.MODERATOR_NEED_APPROVEMENT
page.save()
else:
- plugin.delete_with_public()
+ plugin.delete()
plugin_name = unicode(plugin_pool.get_plugin(plugin.plugin_type).name)
- comment = ugettext(u"%(plugin_name)s plugin at position %(position)s in %(placeholder)s was deleted.") % {
+ comment = _("%(plugin_name)s plugin at position %(position)s in %(placeholder)s was deleted.") % {
'plugin_name': plugin_name,
'position': plugin.position,
'placeholder': plugin.placeholder,
}
+
+ moderator.page_changed(page,
+ force_moderation_action=PageModeratorState.ACTION_CHANGED)
+
if page and 'reversion' in settings.INSTALLED_APPS:
helpers.make_revision_with_plugins(page)
reversion.revision.user = request.user
reversion.revision.comment = comment
return HttpResponse("%s,%s" % (plugin_id, comment))
- def change_moderation(self, request, page_id):
- """Called when user clicks on a moderation checkbox in tree vies, so if he
- wants to add/remove/change moderation required by him. Moderate is sum of
- mask values.
- """
- from cms.models.moderatormodels import MASK_PAGE, MASK_CHILDREN, MASK_DESCENDANTS
- if request.method != 'POST':
- return HttpResponseNotAllowed(['POST'])
- page = get_object_or_404(Page, id=page_id)
- moderate = request.POST.get('moderate', None)
- if moderate is not None and page.has_moderate_permission(request):
- try:
- moderate = int(moderate)
- except:
- moderate = 0
-
- if moderate == 0:
- # kill record with moderation which equals zero
- try:
- page.pagemoderator_set.get(user=request.user).delete()
- except ObjectDoesNotExist:
- pass
- return admin_utils.render_admin_menu_item(request, page)
- elif moderate <= MASK_PAGE + MASK_CHILDREN + MASK_DESCENDANTS:
- page_moderator, created = page.pagemoderator_set.get_or_create(user=request.user)
- # split value to attributes
- page_moderator.set_decimal(moderate)
- page_moderator.save()
- return admin_utils.render_admin_menu_item(request, page)
- raise Http404
-
def lookup_allowed(self, key, *args, **kwargs):
if key == 'site__exact':
return True
View
10 cms/admin/permissionadmin.py
@@ -78,8 +78,6 @@ def get_formset(self, request, obj=None, **kwargs):
exclude.append('can_change_advanced_settings')
if not obj.has_move_page_permission(request):
exclude.append('can_move_page')
- if not settings.CMS_MODERATOR or not obj.has_moderate_permission(request):
- exclude.append('can_moderate')
formset_cls = super(PagePermissionInlineAdmin, self
).get_formset(request, obj=None, exclude=exclude, *kwargs)
qs = self.queryset(request)
@@ -96,7 +94,7 @@ class ViewRestrictionInlineAdmin(PagePermissionInlineAdmin):
exclude = [
'can_add', 'can_change', 'can_delete', 'can_view',
'can_publish', 'can_change_advanced_settings', 'can_move_page',
- 'can_moderate', 'can_change_permissions'
+ 'can_change_permissions'
]
def get_formset(self, request, obj=None, **kwargs):
@@ -133,12 +131,6 @@ class GlobalPagePermissionAdmin(admin.ModelAdmin):
list_display.append('can_change_advanced_settings')
list_filter.append('can_change_advanced_settings')
-
- if settings.CMS_MODERATOR:
- list_display.append('can_moderate')
- list_filter.append('can_moderate')
- else:
- exclude.append('can_moderate')
class GenericCmsPermissionAdmin(object):
View
72 cms/api.py
@@ -7,6 +7,7 @@
calling these methods!
"""
import datetime
+from django.core.exceptions import PermissionDenied
from cms.utils.i18n import get_language_list
from django.conf import settings
@@ -19,9 +20,9 @@
from cms.admin.forms import save_permissions
from cms.app_base import CMSApp
from cms.apphook_pool import apphook_pool
-from cms.models.moderatormodels import ACCESS_PAGE_AND_DESCENDANTS
from cms.models.pagemodel import Page
-from cms.models.permissionmodels import PageUser, PagePermission, GlobalPagePermission
+from cms.models.permissionmodels import (PageUser, PagePermission,
+ GlobalPagePermission, ACCESS_PAGE_AND_DESCENDANTS)
from cms.models.placeholdermodel import Placeholder
from cms.models.pluginmodel import CMSPlugin
from cms.models.titlemodels import Title
@@ -191,9 +192,6 @@ def create_page(title, template, language, menu_title=None, slug=None,
page.insert_at(parent, position)
page.save()
- if settings.CMS_MODERATOR and _thread_locals.user:
- page.pagemoderator_set.create(user=_thread_locals.user)
-
create_title(
language=language,
title=title,
@@ -206,7 +204,10 @@ def create_page(title, template, language, menu_title=None, slug=None,
page=page,
overwrite_url=overwrite_url
)
-
+
+ if published:
+ page.publish()
+
del _thread_locals.user
return page
@@ -332,30 +333,26 @@ def create_page_user(created_by, user,
def assign_user_to_page(page, user, grant_on=ACCESS_PAGE_AND_DESCENDANTS,
can_add=False, can_change=False, can_delete=False,
can_change_advanced_settings=False, can_publish=False,
- can_change_permissions=False, can_move_page=False, can_moderate=False,
+ can_change_permissions=False, can_move_page=False,
can_recover_page=True, can_view=False,
grant_all=False, global_permission=False):
"""
Assigns given user to page, and gives him requested permissions.
See docs/extending_cms/api_reference.rst for more info
"""
- if grant_all and not global_permission:
- # shortcut to grant all permissions
- return assign_user_to_page(page, user, grant_on, True, True, True, True,
- True, True, True, True, True)
-
+ grant_all = grant_all and not global_permission
data = {
- 'can_add': can_add,
- 'can_change': can_change,
- 'can_delete': can_delete,
- 'can_change_advanced_settings': can_change_advanced_settings,
- 'can_publish': can_publish,
- 'can_change_permissions': can_change_permissions,
- 'can_move_page': can_move_page,
- 'can_moderate': can_moderate,
- 'can_view': can_view,
- }
+ 'can_add': can_add or grant_all,
+ 'can_change': can_change or grant_all,
+ 'can_delete': can_delete or grant_all,
+ 'can_change_advanced_settings': can_change_advanced_settings or grant_all,
+ 'can_publish': can_publish or grant_all,
+ 'can_change_permissions': can_change_permissions or grant_all,
+ 'can_move_page': can_move_page or grant_all,
+ 'can_view': can_view or grant_all,
+ }
+
page_permission = PagePermission(page=page, user=user,
grant_on=grant_on, **data)
page_permission.save()
@@ -366,33 +363,20 @@ def assign_user_to_page(page, user, grant_on=ACCESS_PAGE_AND_DESCENDANTS,
page_permission.sites.add(Site.objects.get_current())
return page_permission
-def publish_page(page, user, approve=False):
- """
- Publish a page. This sets `page.published` to `True` and saves it, which
- triggers `cms.utils.moderator.page_changed` which does the actual moderation
- and publishing action.
-
- See docs/extending_cms/api_reference.rst for more info
+def publish_page(page, user):
"""
- page.published = True
- # the magic happens in the post save signal here... WTF?
- page.save()
- # reload page
- page = Page.objects.get(pk=page.pk)
- # approve page if requested
- if approve:
- page = approve_page(page, user)
- return page.reload()
-
-def approve_page(page, user):
- """
- Approve a page version.
+ Publish a page. This sets `page.published` to `True` and calls publish()
+ which does the actual publishing.
See docs/extending_cms/api_reference.rst for more info
"""
class FakeRequest(object):
def __init__(self, user):
self.user = user
request = FakeRequest(user)
- moderator.approve_page(request, page)
- return Page.objects.get(pk=page.pk)
+ if not page.has_publish_permission(request):
+ raise PermissionDenied()
+ page.published = True
+ page.save()
+ page.publish()
+ return page.reload()
View
15 cms/appresolver.py
@@ -2,7 +2,7 @@
from __future__ import with_statement
from cms.apphook_pool import apphook_pool
from cms.utils.i18n import force_language, get_language_list
-from cms.utils.moderator import get_page_queryset
+from cms.utils.page_resolver import get_page_queryset
from django.conf import settings
from django.conf.urls.defaults import patterns
@@ -38,10 +38,7 @@ def applications_page_check(request, current_page=None, path=None):
try:
page_id = resolver.resolve_page_id(path)
# yes, it is application page
- if settings.CMS_MODERATOR:
- page = get_page_queryset(request).get(Q(id=page_id) | Q(publisher_draft=page_id))
- else:
- page = get_page_queryset(request).get(id=page_id)
+ page = get_page_queryset(request).get(id=page_id)
# If current page was matched, then we have some override for content
# from cms, but keep current page. Otherwise return page to which was application assigned.
return page
@@ -178,12 +175,10 @@ def get_app_patterns():
included = []
# we don't have a request here so get_page_queryset() can't be used,
- # so, if CMS_MODERATOR, use, public() queryset, otherwise
- # use draft(). This can be done, because url patterns are used just
- # in frontend
- is_draft = not settings.CMS_MODERATOR
+ # so use public() queryset.
+ # This can be done because url patterns are used just in frontend
- title_qs = Title.objects.filter(page__publisher_is_draft=is_draft, page__site=current_site)
+ title_qs = Title.objects.public().filter(page__site=current_site)
hooked_applications = {}
View
89 cms/cms_toolbar.py
@@ -1,31 +1,29 @@
# -*- coding: utf-8 -*-
+import urllib
from cms.toolbar.base import Toolbar
from cms.toolbar.constants import LEFT, RIGHT
from cms.toolbar.items import (Anchor, Switcher, TemplateHTML, ListItem, List,
GetButton)
from cms.utils import cms_static_url
-from cms.utils.moderator import page_moderator_state, I_APPROVE
from django import forms
from django.conf import settings
from django.contrib.auth import authenticate, login, logout
from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect
from django.utils.translation import ugettext_lazy as _
-import urllib
-from utils.permissions import has_page_change_permission, has_any_page_change_permissions
-from django.conf import settings
+from utils.permissions import has_page_change_permission
def _get_page_admin_url(context, toolbar, **kwargs):
- return reverse('admin:cms_page_change', args=(toolbar.request.current_page.pk,))
+ return reverse('admin:cms_page_change', args=(toolbar.request.current_page.get_draft_object().pk,))
def _get_page_history_url(context, toolbar, **kwargs):
- return reverse('admin:cms_page_history', args=(toolbar.request.current_page.pk,))
+ return reverse('admin:cms_page_history', args=(toolbar.request.current_page.get_draft_object().pk,))
def _get_add_child_url(context, toolbar, **kwargs):
data = {
'position': 'last-child',
- 'target': toolbar.request.current_page.pk,
+ 'target': toolbar.request.current_page.get_draft_object().pk,
}
args = urllib.urlencode(data)
return '%s?%s' % (reverse('admin:cms_page_add'), args)
@@ -35,19 +33,22 @@ def _get_add_sibling_url(context, toolbar, **kwargs):
'position': 'last-child',
}
if toolbar.request.current_page.parent_id:
- data['target'] = toolbar.request.current_page.parent_id
+ data['target'] = toolbar.request.current_page.get_draft_object().parent_id
args = urllib.urlencode(data)
return '%s?%s' % (reverse('admin:cms_page_add'), args)
def _get_delete_url(context, toolbar, **kwargs):
- return reverse('admin:cms_page_delete', args=(toolbar.request.current_page.pk,))
-
-def _get_approve_url(context, toolbar, **kwargs):
- return reverse('admin:cms_page_approve_page', args=(toolbar.request.current_page.pk,))
+ return reverse('admin:cms_page_delete', args=(toolbar.request.current_page.get_draft_object().pk,))
def _get_publish_url(context, toolbar, **kwargs):
- return reverse('admin:cms_page_publish_page', args=(toolbar.request.current_page.pk,))
+ return reverse('admin:cms_page_publish_page', args=(toolbar.request.current_page.get_draft_object().pk,))
+
+def _get_revert_url(context, toolbar, **kwargs):
+ return reverse('admin:cms_page_revert_page', args=(toolbar.request.current_page.get_draft_object().pk,))
+def _page_is_dirty(request):
+ page = request.current_page
+ return page and page.published and page.get_draft_object().is_dirty()
class CMSToolbarLoginForm(forms.Form):
cms_username = forms.CharField()
@@ -58,14 +59,16 @@ class CMSToolbar(Toolbar):
"""
The default CMS Toolbar
"""
+ revert_button = GetButton(RIGHT, 'revert', _("Revert"),
+ url=_get_revert_url, enable=_page_is_dirty)
+
def __init__(self, request):
super(CMSToolbar, self).__init__(request)
self.init()
def init(self):
self.is_staff = self.request.user.is_staff
- self.can_change = (hasattr(self.request.current_page, 'has_change_permission') and
- self.request.current_page.has_change_permission(self.request))
+ self.can_change = has_page_change_permission(self.request)
self.edit_mode_switcher = Switcher(LEFT, 'editmode', 'edit', 'edit-off',
_('Edit mode'))
self.edit_mode = self.is_staff and self.edit_mode_switcher.get_state(self.request)
@@ -81,16 +84,18 @@ def get_items(self, context, **kwargs):
self.page_states = []
-
- if self.is_staff:
-
+ if self.can_change:
items.append(
self.edit_mode_switcher
)
+
+ if self.is_staff:
+
+ current_page = self.request.current_page
- if self.request.current_page:
- states = self.request.current_page.last_page_states()
- has_states = states.exists()
+ if current_page:
+ states = current_page.last_page_states()
+ has_states = bool(len(states))
self.page_states = states
if has_states:
items.append(
@@ -99,30 +104,16 @@ def get_items(self, context, **kwargs):
)
# publish button
- if self.edit_mode and settings.CMS_MODERATOR:
- moderator_state = page_moderator_state(self.request, self.request.current_page)
- should_approve = moderator_state['state'] >= I_APPROVE
- has_perms = self.request.current_page.has_moderate_permission(self.request)
- if should_approve and has_perms:
- label = moderator_state['label']
- urlgetter = _get_approve_url
- elif has_perms:
- label = _("Publish")
- urlgetter = _get_publish_url
- else:
- urlgetter = _get_approve_url
- label = _("Request Approval")
- items.append(
- GetButton(RIGHT, 'moderator', label, urlgetter)
- )
-
- has_global_current_page_change_permission = False
- if settings.CMS_PERMISSION:
- has_global_current_page_change_permission = has_page_change_permission(self.request)
- has_current_page_change_permission = self.request.current_page.has_change_permission(self.request)
+ if self.edit_mode:
+ if current_page.has_publish_permission(self.request):
+ items.append(
+ GetButton(RIGHT, 'moderator', _("Publish"), _get_publish_url)
+ )
+ if self.revert_button.is_enabled_for(self.request):
+ items.append(self.revert_button)
# The 'templates' Menu
- if has_global_current_page_change_permission or has_current_page_change_permission:
+ if self.can_change:
items.append(self.get_template_menu(context, self.can_change, self.is_staff))
# The 'page' Menu
@@ -131,11 +122,7 @@ def get_items(self, context, **kwargs):
# The 'Admin' Menu
items.append(self.get_admin_menu(context, self.can_change, self.is_staff))
- items.append(
- GetButton(RIGHT, 'logout', _('Logout'), '?cms-toolbar-logout',
- cms_static_url('images/toolbar/icons/icon_lock.png'))
- )
- elif not self.request.user.is_authenticated():
+ if not self.request.user.is_authenticated():
items.append(
TemplateHTML(LEFT, 'login', 'cms/toolbar/items/login.html')
)
@@ -148,11 +135,11 @@ def get_items(self, context, **kwargs):
def get_template_menu(self, context, can_change, is_staff):
menu_items = []
- url = reverse('admin:cms_page_change_template', args=(self.request.current_page.pk,))
+ url = reverse('admin:cms_page_change_template', args=(self.request.current_page.get_draft_object().pk,))
for path, name in settings.CMS_TEMPLATES:
args = urllib.urlencode({'template': path})
css = 'template'
- if self.request.current_page.get_template() == path:
+ if self.request.current_page.get_draft_object().get_template() == path:
css += ' active'
menu_items.append(
ListItem(css, name, '%s?%s' % (url, args), 'POST'),
@@ -198,7 +185,7 @@ def get_admin_menu(self, context, can_change, is_staff):
reverse('admin:index'),
icon=cms_static_url('images/toolbar/icons/icon_admin.png')),
]
- if can_change:
+ if can_change and self.request.current_page:
admin_items.append(
ListItem('settings', _('Page Settings'),
_get_page_admin_url,
View
3 cms/conf/__init__.py
@@ -16,9 +16,6 @@ def patch_settings():
return
patch_settings.ALREADY_PATCHED = True
- if getattr(settings, 'CMS_MODERATOR', False):
- warnings.warn("CMS_MODERATOR will be removed and replaced in django CMS 2.4!", CMSDeprecationWarning)
-
from cms.conf import global_settings
# patch settings
View
4 cms/conf/global_settings.py
@@ -115,10 +115,6 @@
# Path (relative to MEDIA_ROOT/MEDIA_URL) to directory for storing page-scope files.
CMS_PAGE_MEDIA_PATH = 'cms_page_media/'
-# moderator mode - if True, approve path can be setup for every page, so there
-# will be some control over the published stuff
-CMS_MODERATOR = False
-
# Defines what character will be used for the __unicode__ handling of cms pages
CMS_TITLE_CHARACTER = '+'
View
2 cms/conf/patch.py
@@ -122,7 +122,7 @@ def post_patch_check():
tmp_language['public'] = True
if tmp_language['public']:
fallbacks.append(tmp_language['code'])
- if fallbacks:
+ if fallbacks and language['code'] in fallbacks:
fallbacks.remove(language['code'])
if settings.CMS_LANGUAGES.has_key('default'):
language['fallbacks'] = settings.CMS_LANGUAGES['default'].get('fallbacks', fallbacks)
View
4 cms/exceptions.py
@@ -37,6 +37,10 @@ class NoPermissionsException(PermissionsException):
"""Can be fired when some violate action is performed on permission system.
"""
+class PublicIsUnmodifiable(Exception):
+ """A method was invoked on the public copy, but is only valid for the
+ draft version"""
+ pass
class Deprecated(Exception): pass
View
8 cms/forms/utils.py
@@ -16,11 +16,9 @@ def update_site_and_page_choices(lang=None):
lang = lang or translation.get_language()
SITE_CHOICES_KEY = get_site_cache_key(lang)
PAGE_CHOICES_KEY = get_page_cache_key(lang)
- if settings.CMS_MODERATOR:
- title_queryset = Title.objects.filter(page__publisher_is_draft=False)
- else:
- title_queryset = Title.objects.filter(page__publisher_is_draft=True)
- title_queryset = title_queryset.select_related('page', 'page__site').order_by('page__tree_id', 'page__lft', 'page__rght')
+ title_queryset = (Title.objects.drafts()
+ .select_related('page', 'page__site')
+ .order_by('page__tree_id', 'page__lft', 'page__rght'))
pages = defaultdict(SortedDict)
sites = {}
for title in title_queryset:
View
41 cms/locale/it/LC_MESSAGES/django.po
@@ -6,16 +6,17 @@
# babu <marco.badan@gmail.com>, 2011.
# Denis Darii <sinednx@gmail.com>, 2011.
# Iacopo Spalletti <i.spalletti@nephila.it>, 2011.
+# <i.spalletti@nephila.it>, 2012.
# karim79 <karim@gorjux.net>, 2011.
# Marco Barberis <mbarberis@gmail.com>, 2011.
# <sbrentegani@gmail.com>, 2011.
msgid ""
msgstr ""
"Project-Id-Version: django-cms\n"
"Report-Msgid-Bugs-To: https://github.com/divio/django-cms/issues\n"
-"POT-Creation-Date: 2012-09-19 14:44+0200\n"
-"PO-Revision-Date: 2012-09-19 14:44+0000\n"
-"Last-Translator: Patrick Lauber <patrick.lauber@divio.ch>\n"
+"POT-Creation-Date: 2012-09-21 14:52+0200\n"
+"PO-Revision-Date: 2012-11-09 15:24+0000\n"
+"Last-Translator: yakky <i.spalletti@nephila.it>\n"
"Language-Team: divio.ch <developers@divio.ch>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
@@ -287,7 +288,7 @@ msgstr "Errore del database"
#: admin/pageadmin.py:779
msgid ""
"Error! You don't have permissions to move this page. Please reload the page"
-msgstr ""
+msgstr "Errore! Non hai il permesso di spostare questa pagina. Ricarica la pagina"
#: admin/pageadmin.py:880
msgid "Page was successfully approved."
@@ -922,15 +923,15 @@ msgstr "Google Map"
#: plugins/googlemap/cms_plugins.py:19
msgid "Advanced"
-msgstr ""
+msgstr "Avanzato"
#: plugins/googlemap/forms.py:23