def root_page(): """ Get the global Wagtail root page (cleared of any subpages it might have) :return: Root page :rtype: wagtail.wagtailcore.models.Page """ try: page = Page.objects.get(slug="root", depth=1) except Page.DoesNotExist: # pragma: no cover page = Page.objects.create( title="Root", slug='root', content_type=ContentType.objects.get_for_model(Page), path='0001', depth=1, numchild=1, url_path='/', ) for child in page.get_children(): # pragma: no cover child.delete() page.numchild = 0 page.save(update_fields=("numchild",)) site = Site.objects.first() if not site: # pragma: no cover site = Site() site.root_page = page site.is_default_site = True site.save() return page
def test_utils_is_recruitment_site(self): factory = RequestFactory() recruitment_site_request = factory.get("/", SERVER_NAME=self.site.hostname) self.assertEqual(Site.find_for_request(recruitment_site_request), self.site) self.assertTrue(is_recruitment_site(self.site)) internal_recruitment_site_request = factory.get( "/", SERVER_NAME=self.site_internal.hostname) self.assertEqual( Site.find_for_request(internal_recruitment_site_request), self.site_internal) self.assertTrue(is_recruitment_site(self.site_internal)) # Create a main site (not recruitment site) main_site_homepage = self.root_page.add_child( instance=HomePageFactory.build_with_fk_objs_committed()) main_site = Site.objects.create(hostname="main.example", port=80, root_page=main_site_homepage) main_site_request = factory.get("/", SERVER_NAME=main_site.hostname) self.assertEqual(Site.find_for_request(main_site_request), main_site) self.assertFalse(is_recruitment_site(main_site))
def test_duplicate_slug(self): try: from wagtail.core.models import Site except ImportError: from wagtail.wagtailcore.models import Site # Create a test Site with a root page root = models.TestRootPage(title='title', depth=1, path='0001', slug_en='slug_en', slug_de='slug_de') root.save() site = Site(root_page=root) site.save() # Add children to the root child = root.add_child( instance=models.TestSlugPage1(title='child1', slug_de='child', slug_en='child-en', depth=2, path='00010001') ) child2 = root.add_child( instance=models.TestSlugPage2(title='child2', slug_de='child-2', slug_en='child2-en', depth=2, path='00010002') ) # Clean should work fine as the two slugs are different child2.clean() # Make the slug equal to test if the duplicate is detected child2.slug_de = 'child' self.assertRaises(ValidationError, child2.clean) child2.slug_de = 'child-2' # Make the translated slug equal to test if the duplicate is detected child2.slug_en = 'child-en' self.assertRaises(ValidationError, child2.clean)
def get(self, request, *args, **kwargs): if not Site.find_for_request(request): raise Http404 if request.resolver_match.url_name == 'blog_page_serve_slug': # Splitting the request path and obtaining the path_components # this way allows you to place the blog at the level you want on # your sitemap. # Example: # splited_path = ['es', 'blog', '2016', '06', '23', 'blog-entry'] # slicing this way you obtain: # path_components = ['es', 'blog', 'blog-entry'] # with the oldest solution you'll get ['es', 'blog-entry'] # and a 404 will be raised split_path = strip_prefix_and_ending_slash(request.path).split("/") path_components = split_path[:-4] + split_path[-1:] else: path_components = [ strip_prefix_and_ending_slash(request.path).split('/')[-1] ] page, args, kwargs = Site.find_for_request( request).root_page.specific.route(request, path_components) for fn in hooks.get_hooks('before_serve_page'): result = fn(page, request, args, kwargs) if isinstance(result, HttpResponse): return result return page.serve(request, *args, **kwargs)
def test_population_and_value_getting(root_page, django_assert_num_queries): domestic_homepage = HomePageFactory(parent=root_page) topic_page = TopicLandingPageFactory(parent=domestic_homepage, slug='topic') article_list_page = ArticleListingPageFactory(parent=topic_page, slug='list') article_page = ArticlePageFactory(parent=article_list_page, slug='article') Site.objects.all().delete() site = Site.objects.create( site_name='Great Domestic', hostname='domestic.trade.great', root_page=domestic_homepage, ) # Trigger population of site root paths cache Site.get_site_root_paths() # Prefetch content type for this page root_page.specific_class # With the two potential queries above out of the way, # population should only use as single datatbase query with django_assert_num_queries(1): result = PageIDCache.populate() # Check result looks as expected assert result == { 'by-path': { f'{site.id}:/': domestic_homepage.id, f'{site.id}:/topic/': topic_page.id, f'{site.id}:/topic/list/': article_list_page.id, f'{site.id}:/topic/list/article/': article_page.id }, 'by-slug': { 'EXPORT_READINESS:great-domestic-home': domestic_homepage.id, 'EXPORT_READINESS:topic': topic_page.id, 'EXPORT_READINESS:list': article_list_page.id, 'EXPORT_READINESS:article': article_page.id, }, } # Check get_for_path() result_1 = PageIDCache.get_for_path('/', site.id) assert result_1 == domestic_homepage.id result_2 = PageIDCache.get_for_path('/topic/list/article/', site.id) assert result_2 == article_page.id # Check invalid get_for_path() assert PageIDCache.get_for_path('123', 99) is None # Check get_for_slug() result_1 = PageIDCache.get_for_slug('topic', 'EXPORT_READINESS') assert result_1 == topic_page.id result_2 = PageIDCache.get_for_slug('article', 'EXPORT_READINESS') assert result_2 == article_page.id # Check invalid get_for_slug() assert PageIDCache.get_for_slug('abc', 'IMPORT_NOT_READINESS') is None
def django_db_setup(django_db_setup, django_db_blocker): with django_db_blocker.unblock(): root_page = Page(title='test', path='test', depth=1) root_page.save() site = Site(hostname='www.example.com', root_page=root_page) site.save() count_settings = AnimalCountSettings(site_id=site.id) count_settings.save()
def test_site_name_default(self): site = Site( hostname="example.com", port=80, site_name="example dot com", is_default_site=True, ) self.assertEqual(site.__str__(), "example dot com [default]")
def setUp(self): self.site = Site.objects.get(is_default_site=True) self.factory = RequestFactory() self.request = self.factory.get("/") if wagtail.VERSION >= (2, 9): # pragma: no cover Site.find_for_request(self.request) else: # pragma: no cover self.request.site = self.site
def test_relative_url(self): try: from wagtail.core.models import Site except ImportError: from wagtail.wagtailcore.models import Site # Create a test Site with a root page root = models.TestRootPage(title='title slugurl', depth=1, path='0004', slug_en='title_slugurl_en', slug_de='title_slugurl_de') root.save() site = Site(root_page=root) site.save() # Add children to the root child = root.add_child( instance=models.TestSlugPage1(title='child1 slugurl', slug_en='child-slugurl-en', slug_de='child-slugurl-de', depth=2, path='00040001')) child.save_revision().publish() url_1_de = child.relative_url(site) self.assertEqual( url_1_de, '/de/child-slugurl-de/', 'When using the default language, slugurl produces the wrong url.') trans_real.activate('en') url_1_en = child.relative_url(site) self.assertEqual( url_1_en, '/en/child-slugurl-en/', 'When using non-default language, slugurl produces the wrong url.') # Add children using non-default language child2 = root.add_child( instance=models.TestSlugPage2(title='child2 slugurl', title_de='child2 slugurl DE', slug_de='child2-slugurl-de', slug_en='child2-slugurl-en', depth=2, path='00040002')) child2.save_revision().publish() url_2_en = child2.relative_url(site) self.assertEqual( url_2_en, '/en/child2-slugurl-en/', 'When using non-default language, slugurl produces the wrong url.') trans_real.activate('de') url_2_de = child2.relative_url(site) self.assertEqual( url_2_de, '/de/child2-slugurl-de/', 'When using non-default language, slugurl produces the wrong url.')
def test_oops_there_is_more_than_one(self): Site.objects.create(hostname='example.com', is_default_site=True, root_page=Page.objects.get(pk=2)) site = Site(hostname='test.com', is_default_site=True, root_page=Page.objects.get(pk=2)) with self.assertRaises(Site.MultipleObjectsReturned): # If there already are multiple default sites, you're in trouble site.clean_fields()
def home_page(): rp = root_page() rp.get_children().delete() hp = root_page().add_child( instance=FrontPage(title='Test Home', live=True)) site = Site(hostname='localhost', is_default_site=True, port=80, site_name='Test site', root_page=hp) site.save() return hp
def test_models_cached(self): """ Accessing a setting should only hit the DB once per render """ request = self.get_request() get_title = '{{ settings.tests.testsetting.title }}' # force site query before hand Site.find_for_request(request) for i in range(1, 4): with self.assertNumQueries(1): self.assertEqual(self.render(request, get_title * i), self.test_setting.title * i)
def test_get_urls_with_request_site_cache_with_i18n(self): request, django_site = self.get_request_and_django_site('/sitemap.xml') req_protocol = request.scheme sitemap = Sitemap(request) # pre-seed find_for_request cache, so that it's not counted towards the query count Site.find_for_request(request) with self.assertNumQueries(16): urls = [url['location'] for url in sitemap.get_urls(1, django_site, req_protocol)] self.assertIn('http://localhost/', urls) # Homepage self.assertIn('http://localhost/hello-world/', urls) # Child page
def test_for_request_result_caching(self): # repeat test to show caching is unique per request instance, # even when the requests are for the same site for i, request in enumerate( [self.get_request(), self.get_request()], 1): with self.subTest(attempt=i): # force site query beforehand Site.find_for_request(request) # only the first lookup should result in a query with self.assertNumQueries(1): for i in range(4): TestSetting.for_request(request)
def test_models_cached(self): """ Accessing a setting should only hit the DB once per request instance, even if using that request to rendering multiple times""" request = self.get_request() get_title = '{{ settings.tests.testsetting.title }}' # force site query beforehand Site.find_for_request(request) with self.assertNumQueries(1): for i in range(1, 4): with self.subTest(attempt=i): self.assertEqual(self.render(request, get_title * i), self.default_site_settings.title * i)
def test_models_cached(self): """ Accessing a setting should only hit the DB once per render """ get_title = '{{ settings("tests.testsetting").title }}' request = self.get_request() # run extra query before hand Site.find_for_request(request) for i in range(1, 4): with self.assertNumQueries(1): context = {'request': request} template = self.engine.from_string(get_title * i) self.assertEqual(template.render(context), self.default_site_settings.title * i)
def test_select_related(self, expected_queries=4): """The `select_related` attribute on setting models is `None` by default, so fetching foreign keys values requires additional queries""" request = self.get_request() self._create_importantpages_object() # force site query beforehand Site.find_for_request(request) # fetch settings and access foreiegn keys with self.assertNumQueries(expected_queries): settings = ImportantPages.for_request(request) settings.sign_up_page settings.general_terms_page settings.privacy_policy_page
def test_with_server_name(self): request = HttpRequest() request.META = { 'SERVER_NAME': 'example.com', 'SERVER_PORT': 80 } self.assertEqual(Site.find_for_request(request), self.site)
def fb_og_description(page, request): site = Site.find_for_request(request) if hasattr(page, "fb_og_description") and page.fb_og_description is not None: return page.fb_og_description else: return MetaTagSettings.for_site(site).description
def get_base_queryset(self): """ Returns a queryset containing all pages that can be seen by this user. This is used as the base for get_queryset and is also used to find the parent pages when using the child_of and descendant_of filters as well. """ # Get live pages that are not in a private section queryset = Page.objects.all().public().live() # Filter by site site = Site.find_for_request(self.request) if site: base_queryset = queryset queryset = base_queryset.descendant_of(site.root_page, inclusive=True) # If internationalisation is enabled, include pages from other language trees if getattr(settings, 'WAGTAIL_I18N_ENABLED', False): for translation in site.root_page.get_translations(): queryset |= base_queryset.descendant_of(translation, inclusive=True) else: # No sites configured queryset = queryset.none() return queryset
def get_form_kwargs(self): kwargs = super().get_form_kwargs() kwargs['user'] = self.request.user kwargs['submission'] = self.submission kwargs['action'] = self.request.GET.get('action') kwargs['site'] = Site.find_for_request(self.request) return kwargs
def _getEventFromUid(self, request, uid): """Try and find an event with the given UID in this site.""" event = getEventFromUid(request, uid) # might raise exception home = Site.find_for_request(request).root_page if event.get_ancestors().filter(id=home.id).exists(): # only return event if it is in the same site return event
def get_context(self, request, contact): site = Site.find_for_request(request) return { 'self': self, 'contact': contact, 'site': site, }
def clerk_slugurl(context, slug): """ Returns the URL for the page that has the given slug. First tries to find a page on the current site. If that fails or a request is not available in the context, then returns the URL for the first page that matches the slug on any site. Based on: https://github.com/wagtail/wagtail/blob/main/wagtail/core/templatetags/wagtailcore_tags.py#L48 """ page = None try: site = Site.find_for_request(context["request"]) current_site = site except KeyError: # No site object found - allow the fallback below to take place. pass else: if current_site is not None: page = ( Page.objects.in_site(current_site).filter(slug=slug).specific().first() ) # If no page is found, fall back to searching the whole tree. if page is None: page = Page.objects.filter(slug=slug).specific().first() if page: # call pageurl() instead of page.relative_url() here so we get the ``accepts_kwarg`` logic return pageurl(context, page)
def get_context(self, request): """ Override the page object's get context method. """ context = super(StandardPage, self).get_context(request) current_site = Site.find_for_request(request) has_featured_lib_expert = self.get_featured_lib_expert()[0] if has_featured_lib_expert: lib_expert_block = self.unpack_lib_expert_block( self.get_featured_lib_expert()[1], current_site) has_libcal_schedule = libcal_id_by_email( lib_expert_block['email']) != '' context['has_featured_lib_expert'] = has_featured_lib_expert context['has_libcal_schedule'] = has_libcal_schedule context['featured_lib_expert'] = self.get_featured_lib_expert()[1] context['featured_lib_expert_name'] = lib_expert_block['person'] context['featured_lib_expert_image'] = lib_expert_block['image'] context['featured_lib_expert_profile'] = lib_expert_block[ 'profile'] context['featured_lib_expert_links'] = lib_expert_block['links'] context['email'] = lib_expert_block['email'] context['has_search_widget'] = self.enable_search_widget return context
def slugurl(context, slug): """ Returns the URL for the page that has the given slug. First tries to find a page on the current site. If that fails or a request is not available in the context, then returns the URL for the first page that matches the slug on any site. """ try: site = Site.find_for_request(context['request']) current_site = site except (KeyError, AttributeError): # No site object found - allow the fallback below to take place. page = None else: page = Page.objects.in_site(current_site).filter(slug=slug).first() # If no page is found, fall back to searching the whole tree. if page is None: page = Page.objects.filter(slug=slug).first() if page: # call pageurl() instead of page.relative_url() here so we get the ``accepts_kwarg`` logic return pageurl(context, page)
def pageurl(context, page, fallback=None): """ Outputs a page's URL as relative (/foo/bar/) if it's within the same site as the current page, or absolute (http://example.com/foo/bar/) if not. If kwargs contains a fallback view name and page is None, the fallback view url will be returned. """ if page is None and fallback: return reverse(fallback) if not hasattr(page, 'relative_url'): raise ValueError("pageurl tag expected a Page object, got %r" % page) try: site = Site.find_for_request(context['request']) current_site = site except KeyError: # request not available in the current context; fall back on page.url return page.url if current_site is None: # request does not correspond to a recognised site; fall back on page.url return page.url # Pass page.relative_url the request object, which may contain a cached copy of # Site.get_site_root_paths() # This avoids page.relative_url having to make a database/cache fetch for this list # each time it's called. return page.relative_url(current_site, request=context.get('request'))
def settings(request): site = Site.find_for_request(request) instance, created = SitePreferences.objects.get_or_create(site=site) form = SitePreferencesForm(instance=instance) form.instance.site = site object_list = get_edit_handler(SitePreferences) if request.method == "POST": instance = SitePreferences.objects.filter(site=site).first() form = SitePreferencesForm(request.POST, instance=instance) if form.is_valid(): form.save() messages.success(request, _('Link checker settings have been updated.')) return redirect('wagtaillinkchecker_settings') else: messages.error( request, _('The form could not be saved due to validation errors')) else: form = SitePreferencesForm(instance=instance) edit_handler = object_list.bind_to_instance(instance=SitePreferences, form=form, request=request) return render(request, 'wagtaillinkchecker/settings.html', { 'form': form, 'edit_handler': edit_handler, })
def get_wagtail_site(self): from wagtail.core.models import Site site = Site.find_for_request(self.request) if site is None: return Site.objects.select_related('root_page').get( is_default_site=True) return site
def header(context, **kwargs): request = context["request"] site = Site.find_for_request(request) header = HeaderSettings.for_site(site) return { "service_name": header.service_name, "service_href": header.service_link.relative_url(site) if header.service_link else "", "service_long_name": header.service_long_name, "transactional": header.transactional, "logo_href": header.logo_link.relative_url(site) if header.logo_link else "", "logo_aria": header.logo_aria, "show_search": header.show_search, "search_action": kwargs.get("search_action", None), "search_field_name": kwargs.get("search_field_name", None), "primary_links": [{ "label": link.label, "url": link.page.relative_url(site) } for link in header.navigation_links.all()], }
def events_this_week(context): """ Displays a week's worth of events. Starts week with Monday, unless today is Sunday. """ request = context['request'] home = Site.find_for_request(request).root_page cal = CalendarPage.objects.live().descendant_of(home).first() calUrl = cal.get_url(request) if cal else None calName = cal.title if cal else None today = timezone.localdate() beginOrd = today.toordinal() if today.weekday() != 6: # Start week with Monday, unless today is Sunday beginOrd -= today.weekday() endOrd = beginOrd + 6 dateFrom = dt.date.fromordinal(beginOrd) dateTo = dt.date.fromordinal(endOrd) if cal: events = cal._getEventsByDay(request, dateFrom, dateTo) else: events = getAllEventsByDay(request, dateFrom, dateTo) return { 'request': request, 'today': today, 'calendarUrl': calUrl, 'calendarName': calName, 'events': events }