更改页面在 URL 中的显示位置
Change where a Page is displayed in the URL
我已经设置了我的网站,其中主要 parental/tree 结构是 Home > Shop > Category > Product"
,其中 >
表示 的父级。
这工作正常,但是当访问 Product(Page)
时,url 被 Wagtail 自动(并且正确地)配置在 /shop/test-category/test-product
。
我想更改它,以便产品实际显示为根级别(即使它不是)。因此,如果用户访问测试产品,它将位于 /test-product/
.
查看文档,RoutablePageMixin
似乎可以解决问题,但我不知道如何实施它。有什么想法吗?
此解决方案将使产品在 URLS:
/shop/test-category/test-product/
/test-product/
方法:
您说得对,您将需要使用 RoutablePageMixin
,请务必在导入前按照说明将其安装在您的 installed_apps 中。
下面的示例将 RoutablePageMixin
添加到您的 HomePage
,因为这是将位于根 /
URL 的页面。我们在尾随 /
.
之前对单个 slug 进行正则表达式检查和匹配
然后我们看看是否可以找到带有该 slug 的 ProductPage
,并提供(或重定向)到该页面。最后,如果没有匹配项,我们将使用当前请求调用 home_page 的 serve
方法来处理其他任何事情。这可能是不正确的 URL 或正确的子页面 URL.
注意事项:
- 如果您在与产品页面相同的 slug 中有一个子页面,则该子页面将永远不会加载,此代码中没有智能可以解决这个问题。如果将来这成为问题,您可以在产品名称和子页面名称的验证中添加一些逻辑。
- 这不考虑 SEO 问题,搜索引擎会将它们视为不同的页面,因此您可能需要考虑在元标记中声明您的 canonical URL。
- 这不会从
/shop/test-category/test-product/
重定向回 /test-product/
- 这可以通过覆盖 ProductPage
上的 serve
方法并重定向到类似 home_page.url + '/' + self.slug
.
示例代码:
# models.py - assuming all your models are in one file
from django.db import models
from django.shortcuts import redirect # only needed if redirecting
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route
from wagtail.core.models import Page
class ProductPage(Page):
price = models.DecimalField(max_digits=5, decimal_places=2)
content_panels = Page.content_panels + [
FieldPanel('price')
]
class HomePage(RoutablePageMixin, Page):
@route(r'^(?P<product_slug>[\w-]+)/$')
def default_view(self, request, product_slug=None):
"""Route will match any `my-product-slug/` after homepage route."""
product_page = Page.objects.exact_type(ProductPage).filter(slug=product_slug).first()
if product_page:
# option 1 - redirect to the product's normal URL (non-permanent redirect)
# return redirect(product_page.specific.url)
# option 2 - render the product page at this URL (no redirect)
return product_page.specific.serve(request)
else:
# process to normal handling of request so correct sub-pages work
return self.serve(request)
我已经设置了我的网站,其中主要 parental/tree 结构是 Home > Shop > Category > Product"
,其中 >
表示 的父级。
这工作正常,但是当访问 Product(Page)
时,url 被 Wagtail 自动(并且正确地)配置在 /shop/test-category/test-product
。
我想更改它,以便产品实际显示为根级别(即使它不是)。因此,如果用户访问测试产品,它将位于 /test-product/
.
查看文档,RoutablePageMixin
似乎可以解决问题,但我不知道如何实施它。有什么想法吗?
此解决方案将使产品在 URLS:
/shop/test-category/test-product/
/test-product/
方法:
您说得对,您将需要使用 RoutablePageMixin
,请务必在导入前按照说明将其安装在您的 installed_apps 中。
下面的示例将 RoutablePageMixin
添加到您的 HomePage
,因为这是将位于根 /
URL 的页面。我们在尾随 /
.
然后我们看看是否可以找到带有该 slug 的 ProductPage
,并提供(或重定向)到该页面。最后,如果没有匹配项,我们将使用当前请求调用 home_page 的 serve
方法来处理其他任何事情。这可能是不正确的 URL 或正确的子页面 URL.
注意事项:
- 如果您在与产品页面相同的 slug 中有一个子页面,则该子页面将永远不会加载,此代码中没有智能可以解决这个问题。如果将来这成为问题,您可以在产品名称和子页面名称的验证中添加一些逻辑。
- 这不考虑 SEO 问题,搜索引擎会将它们视为不同的页面,因此您可能需要考虑在元标记中声明您的 canonical URL。
- 这不会从
/shop/test-category/test-product/
重定向回/test-product/
- 这可以通过覆盖ProductPage
上的serve
方法并重定向到类似home_page.url + '/' + self.slug
.
示例代码:
# models.py - assuming all your models are in one file
from django.db import models
from django.shortcuts import redirect # only needed if redirecting
from wagtail.admin.edit_handlers import FieldPanel
from wagtail.contrib.wagtailroutablepage.models import RoutablePageMixin, route
from wagtail.core.models import Page
class ProductPage(Page):
price = models.DecimalField(max_digits=5, decimal_places=2)
content_panels = Page.content_panels + [
FieldPanel('price')
]
class HomePage(RoutablePageMixin, Page):
@route(r'^(?P<product_slug>[\w-]+)/$')
def default_view(self, request, product_slug=None):
"""Route will match any `my-product-slug/` after homepage route."""
product_page = Page.objects.exact_type(ProductPage).filter(slug=product_slug).first()
if product_page:
# option 1 - redirect to the product's normal URL (non-permanent redirect)
# return redirect(product_page.specific.url)
# option 2 - render the product page at this URL (no redirect)
return product_page.specific.serve(request)
else:
# process to normal handling of request so correct sub-pages work
return self.serve(request)