def initial_data(apps, schema_editor): ContentType = apps.get_model('contenttypes.ContentType') Page = apps.get_model('wagtailcore.Page') Site = apps.get_model('wagtailcore.Site') WebPage = apps.get_model('website.WebPage') # Create page content type webpage_content_type, created = ContentType.objects.get_or_create( model='webpage', app_label='website', ) # Delete the default home page generated by wagtail, # and replace it with a more useful page type. curr_homepage = Page.objects.filter(slug='home').delete() homepage = WebPage.objects.create( title="Home", slug='home', custom_template='coderedcms/pages/home_page.html', content_type=webpage_content_type, path='00010001', depth=2, numchild=0, url_path='/home/', locale_id=Locale.get_default().id, ) # Create a new default site Site.objects.create(hostname='localhost', site_name='Funny Communication', root_page_id=homepage.id, is_default_site=True)
def get(self, request, *args, **kwargs): self.locale = None enable_locale_filter = getattr(settings, "WAGTAIL_I18N_ENABLED", False) if enable_locale_filter: if request.GET.get("locale"): self.locale = get_object_or_404( Locale, language_code=request.GET["locale"]) else: self.locale = Locale.get_default() return super().get(request, *args, **kwargs)
def get_for_object(cls, object): try: return cls.objects.get(object=object) except cls.DoesNotExist: # Raises exception if doesn't exist (let it crash!) instance = object.get_instance(Locale.get_default()) return cls.objects.create( object=object, # TODO: How to deal with duplicate paths? path=cls.get_path(instance), )
def create(request, app_label, model_name): model = get_snippet_model_from_url_params(app_label, model_name) permission = get_permission_name('add', model) if not request.user.has_perm(permission): raise PermissionDenied for fn in hooks.get_hooks('before_create_snippet'): result = fn(request, model) if hasattr(result, 'status_code'): return result instance = model() # Set locale of the new instance if issubclass(model, TranslatableMixin): selected_locale = request.GET.get('locale') if selected_locale: instance.locale = get_object_or_404(Locale, language_code=selected_locale) else: instance.locale = Locale.get_default() # Make edit handler edit_handler = get_snippet_edit_handler(model) edit_handler = edit_handler.bind_to(request=request) form_class = edit_handler.get_form_class() if request.method == 'POST': form = form_class(request.POST, request.FILES, instance=instance) if form.is_valid(): form.save() messages.success( request, _("%(snippet_type)s '%(instance)s' created.") % { 'snippet_type': capfirst(model._meta.verbose_name), 'instance': instance }, buttons=[ messages.button( reverse('wagtailsnippets:edit', args=(app_label, model_name, quote(instance.pk))), _('Edit')) ]) for fn in hooks.get_hooks('after_create_snippet'): result = fn(request, instance) if hasattr(result, 'status_code'): return result urlquery = '' if isinstance(instance, TranslatableMixin ) and instance.locale is not Locale.get_default(): urlquery = '?locale=' + instance.locale.language_code return redirect( reverse('wagtailsnippets:list', args=[app_label, model_name]) + urlquery) else: messages.validation_error( request, _("The snippet could not be created due to errors."), form) else: form = form_class(instance=instance) edit_handler = edit_handler.bind_to(instance=instance, form=form) context = { 'model_opts': model._meta, 'edit_handler': edit_handler, 'form': form, 'action_menu': SnippetActionMenu(request, view='create', model=model), 'locale': None, 'translations': [], } if getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and issubclass( model, TranslatableMixin): context.update({ 'locale': instance.locale, 'translations': [{ 'locale': locale, 'url': reverse('wagtailsnippets:add', args=[app_label, model_name]) + '?locale=' + locale.language_code } for locale in Locale.objects.all().exclude(id=instance.locale.id) ], }) return TemplateResponse(request, 'wagtailsnippets/snippets/create.html', context)
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) items = self.model.objects.all() enable_locale_filter = getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and issubclass( self.model, TranslatableMixin) if enable_locale_filter: if 'locale' in self.request.GET: try: locale = Locale.objects.get( language_code=self.request.GET['locale']) except Locale.DoesNotExist: # Redirect to snippet without locale return redirect('wagtailsnippets:list', self.app_label, self.model_name) else: # Default to active locale (this will take into account the user's chosen admin language) locale = Locale.get_active() items = items.filter(locale=locale) else: locale = None # Preserve the snippet's model-level ordering if specified, but fall back on PK if not # (to ensure pagination is consistent) if not items.ordered: items = items.order_by('pk') # Search is_searchable = class_is_indexed(self.model) is_searching = False search_query = None if is_searchable and 'q' in self.request.GET: search_form = SearchForm( self.request.GET, placeholder=_("Search %(snippet_type_name)s") % {'snippet_type_name': self.model._meta.verbose_name_plural}) if search_form.is_valid(): search_query = search_form.cleaned_data['q'] search_backend = get_search_backend() items = search_backend.search(search_query, items) is_searching = True else: search_form = SearchForm( placeholder=_("Search %(snippet_type_name)s") % {'snippet_type_name': self.model._meta.verbose_name_plural}) paginator = Paginator(items, per_page=20) paginated_items = paginator.get_page(self.request.GET.get('p')) context.update({ 'model_opts': self.model._meta, 'items': paginated_items, 'can_add_snippet': self.request.user.has_perm(get_permission_name('add', self.model)), 'can_delete_snippets': self.request.user.has_perm( get_permission_name('delete', self.model)), 'is_searchable': is_searchable, 'search_form': search_form, 'is_searching': is_searching, 'query_string': search_query, 'locale': None, 'translations': [], }) if enable_locale_filter: context.update({ 'locale': locale, 'translations': [{ 'locale': locale, 'url': reverse('wagtailsnippets:list', args=[self.app_label, self.model_name]) + '?locale=' + locale.language_code } for locale in Locale.objects.all().exclude(id=locale.id)], }) return context
def create(request, app_label, model_name): model = get_snippet_model_from_url_params(app_label, model_name) permission = get_permission_name("add", model) if not request.user.has_perm(permission): raise PermissionDenied for fn in hooks.get_hooks("before_create_snippet"): result = fn(request, model) if hasattr(result, "status_code"): return result instance = model() # Set locale of the new instance if issubclass(model, TranslatableMixin): selected_locale = request.GET.get("locale") if selected_locale: instance.locale = get_object_or_404(Locale, language_code=selected_locale) else: instance.locale = Locale.get_default() # Make edit handler edit_handler = get_snippet_edit_handler(model) edit_handler = edit_handler.bind_to(request=request) form_class = edit_handler.get_form_class() if request.method == "POST": form = form_class(request.POST, request.FILES, instance=instance) if form.is_valid(): with transaction.atomic(): form.save() log(instance=instance, action="wagtail.create") messages.success( request, _("%(snippet_type)s '%(instance)s' created.") % { "snippet_type": capfirst(model._meta.verbose_name), "instance": instance, }, buttons=[ messages.button( reverse( "wagtailsnippets:edit", args=(app_label, model_name, quote(instance.pk)), ), _("Edit"), ) ], ) for fn in hooks.get_hooks("after_create_snippet"): result = fn(request, instance) if hasattr(result, "status_code"): return result urlquery = "" if (isinstance(instance, TranslatableMixin) and instance.locale is not Locale.get_default()): urlquery = "?locale=" + instance.locale.language_code return redirect( reverse("wagtailsnippets:list", args=[app_label, model_name]) + urlquery) else: messages.validation_error( request, _("The snippet could not be created due to errors."), form) else: form = form_class(instance=instance) edit_handler = edit_handler.bind_to(instance=instance, form=form) context = { "model_opts": model._meta, "edit_handler": edit_handler, "form": form, "action_menu": SnippetActionMenu(request, view="create", model=model), "locale": None, "translations": [], } if getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass( model, TranslatableMixin): context.update({ "locale": instance.locale, "translations": [{ "locale": locale, "url": reverse("wagtailsnippets:add", args=[app_label, model_name]) + "?locale=" + locale.language_code, } for locale in Locale.objects.all().exclude(id=instance.locale.id) ], }) return TemplateResponse(request, "wagtailsnippets/snippets/create.html", context)
def get_context_data(self, **kwargs): context = super().get_context_data(**kwargs) items = self.model.objects.all() enable_locale_filter = getattr(settings, "WAGTAIL_I18N_ENABLED", False) and issubclass( self.model, TranslatableMixin) if enable_locale_filter: if "locale" in self.request.GET: try: locale = Locale.objects.get( language_code=self.request.GET["locale"]) except Locale.DoesNotExist: # Redirect to snippet without locale return redirect("wagtailsnippets:list", self.app_label, self.model_name) else: # Default to active locale (this will take into account the user's chosen admin language) locale = Locale.get_active() items = items.filter(locale=locale) else: locale = None # Preserve the snippet's model-level ordering if specified, but fall back on PK if not # (to ensure pagination is consistent) if not items.ordered: items = items.order_by("pk") # Search is_searchable = class_is_indexed(self.model) is_searching = False search_query = None if is_searchable and "q" in self.request.GET: search_form = SearchForm( self.request.GET, placeholder=_("Search %(snippet_type_name)s") % {"snippet_type_name": self.model._meta.verbose_name_plural}, ) if search_form.is_valid(): search_query = search_form.cleaned_data["q"] search_backend = get_search_backend() items = search_backend.search(search_query, items) is_searching = True else: search_form = SearchForm( placeholder=_("Search %(snippet_type_name)s") % {"snippet_type_name": self.model._meta.verbose_name_plural}) paginator = Paginator(items, per_page=20) paginated_items = paginator.get_page(self.request.GET.get("p")) context.update({ "model_opts": self.model._meta, "items": paginated_items, "can_add_snippet": self.request.user.has_perm(get_permission_name("add", self.model)), "can_delete_snippets": self.request.user.has_perm( get_permission_name("delete", self.model)), "is_searchable": is_searchable, "search_form": search_form, "is_searching": is_searching, "query_string": search_query, "locale": None, "translations": [], }) if enable_locale_filter: context.update({ "locale": locale, "translations": [{ "locale": locale, "url": reverse( "wagtailsnippets:list", args=[self.app_label, self.model_name], ) + "?locale=" + locale.language_code, } for locale in Locale.objects.all().exclude(id=locale.id)], }) return context
def setUp(self): self.src_locale = Locale.get_default() self.locale = Locale.objects.create(language_code="fr")
def test_get_active_overridden(self): with translation.override("fr"): self.assertEqual(Locale.get_active().language_code, "fr")
def test_get_active_default(self): self.assertEqual(Locale.get_active().language_code, "en")
def test_default_doesnt_have_to_be_english(self): locale = Locale.get_default() self.assertEqual(locale.language_code, "fr")
def test_default(self): locale = Locale.get_default() self.assertEqual(locale.language_code, "en")
def browse(request, parent_page_id=None): # A missing or empty page_type parameter indicates 'all page types' # (i.e. descendants of wagtailcore.page) page_type_string = request.GET.get("page_type") or "wagtailcore.page" user_perm = request.GET.get("user_perms", False) try: desired_classes = page_models_from_string(page_type_string) except (ValueError, LookupError): raise Http404 # Find parent page if parent_page_id: parent_page = get_object_or_404(Page, id=parent_page_id) elif desired_classes == (Page,): # Just use the root page parent_page = Page.get_first_root_node() else: # Find the highest common ancestor for the specific classes passed in # In many cases, such as selecting an EventPage under an EventIndex, # this will help the administrator find their page quicker. all_desired_pages = Page.objects.all().type(*desired_classes) parent_page = all_desired_pages.first_common_ancestor() parent_page = parent_page.specific # Get children of parent page (without streamfields) pages = parent_page.get_children().defer_streamfields().specific() # allow hooks to modify the queryset for hook in hooks.get_hooks("construct_page_chooser_queryset"): pages = hook(pages, request) # Filter them by page type if desired_classes != (Page,): # restrict the page listing to just those pages that: # - are of the given content type (taking into account class inheritance) # - or can be navigated into (i.e. have children) choosable_pages = pages.type(*desired_classes) descendable_pages = pages.filter(numchild__gt=0) pages = choosable_pages | descendable_pages can_choose_root = request.GET.get("can_choose_root", False) target_pages = Page.objects.filter( pk__in=[int(pk) for pk in request.GET.get("target_pages", "").split(",") if pk] ) match_subclass = request.GET.get("match_subclass", True) # Do permission lookups for this user now, instead of for every page. permission_proxy = UserPagePermissionsProxy(request.user) # Parent page can be chosen if it is a instance of desired_classes parent_page.can_choose = can_choose_page( parent_page, permission_proxy, desired_classes, can_choose_root, user_perm, target_pages=target_pages, match_subclass=match_subclass, ) selected_locale = None locale_options = [] show_locale_labels = getattr(settings, "WAGTAIL_I18N_ENABLED", False) if show_locale_labels: pages = pages.select_related("locale") if parent_page_id is None: # 'locale' is the current value of the "Locale" selector in the UI if request.GET.get("locale"): selected_locale = get_object_or_404( Locale, language_code=request.GET["locale"] ) active_locale_id = selected_locale.pk else: active_locale_id = Locale.get_active().pk # we are at the Root level, so get the locales from the current pages choose_url = reverse("wagtailadmin_choose_page") locale_options = [ { "locale": locale, "url": choose_url + "?" + urlencode( {"page_type": page_type_string, "locale": locale.language_code} ), } for locale in Locale.objects.filter( pk__in=pages.values_list("locale_id") ).exclude(pk=active_locale_id) ] else: # We have a parent page (that is not the root page). Use its locale as the selected localer selected_locale = parent_page.locale # and get the locales based on its available translations locales_and_parent_pages = { item["locale"]: item["pk"] for item in Page.objects.translation_of(parent_page).values( "locale", "pk" ) } locales_and_parent_pages[selected_locale.pk] = parent_page.pk for locale in Locale.objects.filter( pk__in=list(locales_and_parent_pages.keys()) ).exclude(pk=selected_locale.pk): choose_child_url = reverse( "wagtailadmin_choose_page_child", args=[locales_and_parent_pages[locale.pk]], ) locale_options.append( { "locale": locale, "url": choose_child_url + "?" + urlencode({"page_type": page_type_string}), } ) # finally, filter the browseable pages on the selected locale if selected_locale: pages = pages.filter(locale=selected_locale) # Pagination # We apply pagination first so we don't need to walk the entire list # in the block below paginator = Paginator(pages, per_page=25) pages = paginator.get_page(request.GET.get("p")) # Annotate each page with can_choose/can_decend flags for page in pages: page.can_choose = can_choose_page( page, permission_proxy, desired_classes, can_choose_root, user_perm, target_pages=target_pages, match_subclass=match_subclass, ) page.can_descend = page.get_children_count() # Render context = shared_context( request, { "parent_page": parent_page, "parent_page_id": parent_page.pk, "pages": pages, "search_form": SearchForm(), "page_type_string": page_type_string, "page_type_names": [ desired_class.get_verbose_name() for desired_class in desired_classes ], "page_types_restricted": (page_type_string != "wagtailcore.page"), "show_locale_labels": show_locale_labels, "locale_options": locale_options, "selected_locale": selected_locale, }, ) return render_modal_workflow( request, "wagtailadmin/chooser/browse.html", None, context, json_data={"step": "browse", "parent_page_id": context["parent_page_id"]}, )
def _push(repo, logger): reader = repo.reader() writer = repo.writer() # Note: Reader is None on initial commit if reader: writer.copy_unmanaged_files(reader) def update_po(filename, new_po): if reader is not None: try: current_po_string = reader.read_file(filename).decode("utf-8") except KeyError: pass else: current_po = polib.pofile(current_po_string, wrapwidth=200) # Take metadata from existing PO file translation_id = new_po.metadata.get( "X-WagtailLocalize-TranslationID") new_po.metadata = current_po.metadata if translation_id: new_po.metadata[ "X-WagtailLocalize-TranslationID"] = translation_id writer.write_file(filename, str(new_po)) source_locale = Locale.get_default() target_locales = Locale.objects.exclude(id=source_locale.id) paths = defaultdict(list) for translation in (Translation.objects.filter( source__locale=source_locale, target_locale__in=target_locales, enabled=True).select_related( "source", "target_locale").order_by("target_locale__language_code")): resource = Resource.get_for_object(translation.source.object) source_po = translation.source.export_po() source_po_filename = po_filename_for_object(resource) update_po(str(source_po_filename), source_po) locale_po = translation.export_po() update_po( str( po_filename_for_object( resource, target_locale=translation.target_locale)), locale_po, ) paths[(source_po_filename, locale_po_filename_template_for_object(resource))].append( translation.target_locale) paths = [(source_filename, locale_filename, locales) for (source_filename, locale_filename), locales in paths.items()] writer.write_config( [locale.language_code for locale in target_locales], paths, # TODO as_rfc5646_language_tag ) if writer.has_changes(): previous_commit = repo.get_head_commit_id() # Create a new log for this push log = SyncLog.objects.create(action=SyncLog.ACTION_PUSH, commit_id="") logger.info("Push: Committing changes") log.commit_id = writer.commit("Updates to source content") log.save(update_fields=["commit_id"]) successful_push = repo.push() if not successful_push: raise SyncPushError(f"Failed to push reference {log.commit_id}") # Add any resources that have changed to the log # This ignores any deletions since we don't care about those for _filename, _old_content, new_content in repo.get_changed_files( previous_commit, log.commit_id): # Note: get_changed_files only picks up changes in the locales/ folder so we can assume they're all PO # files and they have a Translation ID # (anything else that gets in there won't be written into the new commit so, effectively, they get deleted) po = polib.pofile(new_content.decode("utf-8")) translation = Translation.objects.get( uuid=po.metadata["X-WagtailLocalize-TranslationID"]) log.add_translation(translation) else: logger.info( "Push: Not committing anything as recent changes haven't affected any translatable content" )
def list(request, app_label, model_name): model = get_snippet_model_from_url_params(app_label, model_name) permissions = [ get_permission_name(action, model) for action in ['add', 'change', 'delete'] ] if not any([request.user.has_perm(perm) for perm in permissions]): raise PermissionDenied items = model.objects.all() enable_locale_filter = getattr(settings, 'WAGTAIL_I18N_ENABLED', False) and issubclass( model, TranslatableMixin) if enable_locale_filter: if 'locale' in request.GET: try: locale = Locale.objects.get( language_code=request.GET['locale']) except Locale.DoesNotExist: # Redirect to snippet without locale return redirect('wagtailsnippets:list', app_label, model_name) else: # Default to active locale (this will take into account the user's chosen admin language) locale = Locale.get_active() items = items.filter(locale=locale) else: locale = None # Preserve the snippet's model-level ordering if specified, but fall back on PK if not # (to ensure pagination is consistent) if not items.ordered: items = items.order_by('pk') # Search is_searchable = class_is_indexed(model) is_searching = False search_query = None if is_searchable and 'q' in request.GET: search_form = SearchForm( request.GET, placeholder=_("Search %(snippet_type_name)s") % {'snippet_type_name': model._meta.verbose_name_plural}) if search_form.is_valid(): search_query = search_form.cleaned_data['q'] search_backend = get_search_backend() items = search_backend.search(search_query, items) is_searching = True else: search_form = SearchForm( placeholder=_("Search %(snippet_type_name)s") % {'snippet_type_name': model._meta.verbose_name_plural}) paginator = Paginator(items, per_page=20) paginated_items = paginator.get_page(request.GET.get('p')) # Template if request.is_ajax(): template = 'wagtailsnippets/snippets/results.html' else: template = 'wagtailsnippets/snippets/type_index.html' context = { 'model_opts': model._meta, 'items': paginated_items, 'can_add_snippet': request.user.has_perm(get_permission_name('add', model)), 'can_delete_snippets': request.user.has_perm(get_permission_name('delete', model)), 'is_searchable': is_searchable, 'search_form': search_form, 'is_searching': is_searching, 'query_string': search_query, 'locale': None, 'translations': [], } if enable_locale_filter: context.update({ 'locale': locale, 'translations': [{ 'locale': locale, 'url': reverse('wagtailsnippets:list', args=[app_label, model_name]) + '?locale=' + locale.language_code } for locale in Locale.objects.all().exclude(id=locale.id)], }) return TemplateResponse(request, template, context)