【问题标题】:Wagtail multisite on same domain同一域上的 Wagtail 多站点
【发布时间】:2023-03-29 08:55:01
【问题描述】:

我需要创建一个多站点配置,让我可以为不同的站点使用相同的域。

我需要实现的 URL 的一些示例:

subdomain.example.com  (Home for all sites)
|
---subdomain.example.com/common-page/  (Common page for all sites)
|
---subdomain.example.com/common-page-2/  (Common page for all sites)
|
--- subdomain.example.com/news/  (News from all sites)
|
--- subdomain.example.com/site-1/  (Redirects to Home subdomain.example.com)
|
--- subdomain.example.com/site-2/  (Redirects to Home subdomain.example.com)
|
--- subdomain.example.com/site-1/news/  (Site 1 news)
|
--- subdomain.example.com/site-3/news/  (Site 3 news)
|
--- subdomain.example.com/site-1/contact/  (Contact form site 1)
|
--- subdomain.example.com/site-3/contact/  (Contact form site 3)

我可以只在一个站点上创建这个结构,但是在 wagtail 管理员上管理它会很痛苦。

【问题讨论】:

  • 在 Wagtail 的术语中,站点和域是完全相同的,因此“同一个域上的多个站点”没有意义。您希望 Wagtail 在此处执行与单站点安装不同的确切操作吗? (请记住,Wagtail 将始终将您的所有页面显示为一棵树,无论您配置了多少个站点/域。)
  • 与单一站点安装的不同之处在于每个站点都有自己的联系表、新闻和事件。现在我已经配置了 3 个站点,并且资源管理器树向我显示了 3 个站点,使其更易于管理,但是其中 2 个站点上的页面无法访问(错误 404)
  • 好的,让我重新提出我的问题:是什么阻止您创建所需的页面,作为主页的子级,以便它们在页面树中的位置与您想要的 URL 相匹配?
  • 更简单的站点管理是唯一阻止我创建 1 个站点(3 个具有不同新闻/事件的站点与 1 个具有 3 个子页面新闻/事件的站点)的原因。但对于后端实现这一目标所需的努力,这似乎是一个很小的用户体验改进。无论如何,感谢 gasman 让我更清楚地了解这一点。

标签: django wagtail multisite


【解决方案1】:

为未来的询问者回答一个老问题。 @gasman 在上面的comment 中解决了这个问题:

在 Wagtail 的术语中,站点和域完全相同 事情,所以“同一个域上的多个站点”没有意义。

但是,我可以使用以下步骤解决此问题。

我需要这种安排,以便不同站点范围的设置可用于mainsite.commainsite.com/subsite(示例名称)。

虽然我总是可以在我编写的代码中为我网站的不同部分强制执行不同的设置,但我希望这也适用于第三方软件包,例如 wagtailmenus 等。

例如我希望mysite.com 上所有页面的菜单项与mainsite.com/subsite 下所有页面的菜单项不同。

请注意,这是一种粗略的方法,并且可能会出现无法预料的问题。但是,到目前为止,它对我来说效果很好。

  1. 在 Wagtail 管理员中为您的子网站创建一个新网站。
    使用与 mainsite 相同的hostname,但在末尾添加一个点以满足唯一性。无论如何,我们不会使用这个hostname
    此外,使用与mainsite 相同的根页面。这是为了正确生成 URL。

  2. 创建一个小型中间件:

    if request.path.startswith('/subsite'):
        # find subsite and mainsite using Site.objects.filter(site_name='') queries
        subsite.hostname = mainsite.hostname
        request._wagtail_site = subsite
    

    这将确保到达子站点的所有请求都获得其特定的_wagtail_site 属性,但具有正确的hostname。这将使您的代码和第三方包中的所有其他代码将站点确定为子站点。但是,如果第三方包使用 Django 的 site 而不是 Wagtail 的 Site,我不确定这是否仍然有效。

  3. 通常,您不希望将 子网站 设置为默认网站。要强制执行此操作,请在您的任何应用程序的 admin.py 中包含以下内容(我还添加了一些额外的验证):

    def clean_subsite(self):
        instance = self
        if instance.site_name != 'Subsite': return
        super(Site, self).clean()
        if instance.is_default_site:
            raise ValidationError({'is_default_site': ["'Subsite' cannot be made the default website."]})
    
        mainsite = Site.objects.filter(site_name='Mainsite').first()
        if not mainsite:
            raise ValidationError({'hostname': ["'Mainsite' must exist before saving 'Subsite'."]})
    
        if instance.hostname != (mainsite.hostname + '.'):
            raise ValidationError({'hostname': ["Hostname for Subsite is just a placeholder (Subsite uses the same domain as Mainsite does)." +
            " Use the Mainsite's hostname with a '.' as suffix for satisfying uniqueness constraint."]})
    
    from wagtail.core.models import Site
    Site.add_to_class("clean", clean_subsite)
    

    由于上面的Site 过滤查询使用的是site_name='',因此不要在管理中更改MainsiteSubsite 的名称(不要在代码)。

  4. 最后,请注意Page.objects.in_site() 查询对于mainsitesubsite 将无法正常工作。
    要么不使用in_site(),要么覆盖它。 该函数使用:

    self.descendant_of(site.root_page, inclusive=True)
    

    对于主站点,我们需要排除subsite 的根页面的后代。 对于子站点,我们只需要包含subsite 的根页面的后代。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-19
    • 2015-05-08
    • 1970-01-01
    • 2018-03-20
    • 1970-01-01
    • 1970-01-01
    • 2017-10-15
    • 1970-01-01
    相关资源
    最近更新 更多