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_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 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_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_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_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_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_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 get_object(self): path = self.request.GET.get("html_path", None) if path is None: raise ValidationError({"html_path": "Missing value"}) if not path.startswith("/"): path = "/" + path site = Site.find_for_request(self.request) if not site: raise Http404 root_page = site.root_page path_components = [ component for component in path.split("/") if component ] if getattr(settings, 'WAGTAIL_I18N_ENABLED', False): language_from_path = translation.get_language_from_path(path) if language_from_path: path_components.remove(language_from_path) translated_root_page = (root_page.get_translations( inclusive=True).filter( locale__language_code=language_from_path).first()) if not translated_root_page: raise Http404 root_page = translated_root_page page, args, kwargs = root_page.specific.route(self.request, path_components) return page, args, kwargs
def listing_view(self, request): page, args, kwargs = self.get_object() for restriction in page.get_view_restrictions(): if not restriction.accept_request(request): if restriction.restriction_type == PageViewRestriction.PASSWORD: return Response({ "component_name": "PasswordProtectedPage", "component_props": { "restriction_id": restriction.id, "page_id": page.id, "csrf_token": csrf_middleware.get_token(request), }, }) elif restriction.restriction_type in [ PageViewRestriction.LOGIN, PageViewRestriction.GROUPS, ]: site = Site.find_for_request(self.request) resp = require_wagtail_login( next=page.relative_url(site, request)) return Response({ "redirect": { "destination": resp.url, "is_permanent": False, } }) return page.serve(request, *args, **kwargs)
def get_sitemap_urls(self, request=None): return [{ 'location': '{}/press/'.format(Site.find_for_request(request).root_url), 'lastmod': (self.last_published_at or self.latest_revision_created_at), }]
def template_settings(request): """Template context processor: add selected setting to context so it can be used on any page .""" feature_flags = getattr(settings, "FEATURE_FLAGS", []) # default social preview image, relative to static url if "purple-mode" in feature_flags: default_preview_img = "img/alt-modes/purple/cdhlogo_square.png" else: default_preview_img = "img/cdhlogo_square.jpg" context_extras = { "SHOW_TEST_WARNING": getattr(settings, "SHOW_TEST_WARNING", False), "site": Site.find_for_request(request), "default_preview_image": absolutize_url("".join([settings.STATIC_URL, default_preview_img])), # Include analytics based on settings.DEBUG or override in settings.py # Defaults to opposite of settings.DEBUG "INCLUDE_ANALYTICS": getattr(settings, "INCLUDE_ANALYTICS", not settings.DEBUG), # pass any feature flags that are configured "FEATURE_FLAGS": feature_flags, "FAVICON": favicon_path(), } return context_extras
def token(request, site_id=None): """Generate the token. Will detect Wagalyics Multisite settings. Defaults to single-site settings. """ if hasattr(settings, 'WAGALYTICS_SETTINGS'): if site_id is None: site_id = Site.find_for_request(request).id wagalytics_settings = settings.WAGALYTICS_SETTINGS[site_id] if wagalytics_settings.get('GA_KEY_CONTENT', None): access_token = get_access_token_from_str( wagalytics_settings['GA_KEY_CONTENT']) elif wagalytics_settings.get('GA_KEY_FILEPATH', None): access_token = get_access_token( wagalytics_settings['GA_KEY_FILEPATH']) else: return HttpResponseForbidden() else: if (hasattr(settings, 'GA_KEY_CONTENT') and settings.GA_KEY_CONTENT != ''): access_token = get_access_token_from_str(settings.GA_KEY_CONTENT) elif (hasattr(settings, 'GA_KEY_FILEPATH') and settings.GA_KEY_FILEPATH != ''): access_token = get_access_token(settings.GA_KEY_FILEPATH) else: return HttpResponseForbidden() return HttpResponse(access_token)
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 twitter_card_image(page, request): site = Site.find_for_request(request) if hasattr(page, "twitter_card_image") and page.twitter_card_image is not None: return page.twitter_card_image else: return MetaTagSettings.for_site(site).image
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 twitter_card_description(page, request): site = Site.find_for_request(request) if (hasattr(page, "twitter_card_description") and page.twitter_card_description is not None): return page.twitter_card_description else: return MetaTagSettings.for_site(site).description
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 get_context(self, request, contact): site = Site.find_for_request(request) return { 'self': self, 'contact': contact, 'site': site, }
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_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 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 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 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 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 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 }
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 process_request(self, request): """ Set request.site to contain the Site object responsible for handling this request, according to hostname matching rules """ try: request.site = Site.find_for_request(request) except Site.DoesNotExist: request.site = None
def setUp(self): self.home_page = Page.objects.get(id=2) self.routable_page = self.home_page.add_child(instance=RoutablePageTest( title="Routable Page", live=True, )) self.rf = RequestFactory() self.request = self.rf.get(self.routable_page.url) self.request.site = Site.find_for_request(self.request) self.context = {'request': self.request}
def process_request(self, request): if request.path.startswith('/admin/pages/') and \ not request.path.startswith('/admin/pages/moderation/'): current_site = Site.find_for_request(request) func, args, kwargs = resolve(request.path) if args: p_site = Page.objects.get(pk=args[-1]).specific.get_site() if p_site and not current_site == p_site: return redirect('%s%s' % (p_site.root_url, request.path)) if not Languages.for_site(request.site).languages.all().exists(): return redirect('%s/admin/' % request.site.root_url)
def setUp(self): default_site = Site.objects.get(is_default_site=True) second_site = Site.objects.create( # add another site with the same root page hostname='development.local', port=default_site.port, root_page_id=default_site.root_page_id, ) self.home_page = Page.objects.get(id=2) self.routable_page = self.home_page.add_child(instance=RoutablePageTest( title="Routable Page", live=True, )) self.rf = RequestFactory() self.request = self.rf.get(self.routable_page.url) self.request.site = Site.find_for_request(self.request) self.context = {'request': self.request} self.request.site = second_site
def setUp(self): self.home_page = Page.objects.get(id=2) events_page = self.home_page.add_child(instance=Page(title='Events', live=True)) second_site = Site.objects.create( hostname='events.local', port=80, root_page=events_page, ) self.routable_page = self.home_page.add_child(instance=RoutablePageTest( title="Routable Page", live=True, )) self.rf = RequestFactory() self.request = self.rf.get(self.routable_page.url) self.request.site = Site.find_for_request(self.request) self.context = {'request': self.request} self.request.site = second_site
def dispatch(self, request, *args, **kwargs): site = Site.find_for_request(request) return redirect( self.model_admin.url_helper.get_action_url('edit', site.pk))
def test_with_x_forwarded_host(self): with self.settings(USE_X_FORWARDED_HOST=True): request = HttpRequest() request.META = {'HTTP_X_FORWARDED_HOST': 'example.com', 'SERVER_PORT': 80} self.assertEqual(Site.find_for_request(request), self.site)
def test_with_unknown_host(self): request = HttpRequest() request.META = {'HTTP_HOST': 'unknown.com', 'SERVER_PORT': 80} self.assertEqual(Site.find_for_request(request), self.default_site)
def test_default(self): request = HttpRequest() self.assertEqual(Site.find_for_request(request), self.default_site)
def test_with_host(self): request = HttpRequest() request.META = {'HTTP_HOST': 'example.com', 'SERVER_PORT': 80} self.assertEqual(Site.find_for_request(request), self.site)