【问题标题】:Single piece of content, multiple URLs?单个内容,多个 URL?
【发布时间】:2017-06-05 16:38:01
【问题描述】:

我有一个用例,我可以使用一些建议。

我们发布多个产品,每个产品在网站上都有自己的子树。通常,一条内容仅发布到单个产品,例如一篇新闻文章被发布到产品 A 并且可以通过一个 URL 访问。

但是,有时我们希望将内容发布到多个产品,例如一篇新闻文章会发布到产品 A、B 和 C,并将在 3 个不同的 URL 上提供。

在我们当前的 CMS 中,我们最终通过复制和粘贴内容来完成此操作,这对编辑来说是一件麻烦事,尤其是在内容需要更新时。

一个理想的场景是编辑者在一个地方编辑内容,指定要发布到的产品,并且内容由多个 URL 和特定于产品的模板提供。

RoutablePageMixin 似乎在这里很有用,但我不确定如何让编辑器指定目标产品并让路由知道该选择。

有没有人用 Wagtail 解决过类似的问题?

【问题讨论】:

    标签: wagtail


    【解决方案1】:

    我在 Wagtail 中解决了一个类似的问题,RoutablePageMixin 是解决这个问题的关键。

    如果你有 /blog/A/slug-product/, /blog/B/slug-product/, /blog/C/slug-product/ ,那么你可以在这里得到slug值slug-product,然后使用这个值在你的数据库中搜索不同的内容。

    class BlogPage(RoutablePageMixin, Page):
        def get_posts(self):
            return PostPage.objects.descendant_of(self).live()
        @route(r'^(\d{4})/(\d{2})/(\d{2})/(.+)/$')
        def post_by_date_slug(self, request, year, month, day, slug, *args, **kwargs):
            post_page = self.get_posts().filter(slug=slug).first()
            return Page.serve(post_page, request, *args, **kwargs)
    

    如您所见,我没有使用url的日期信息而是使用slug值来获取博客文章对象,您可以按照此处的模式使用正则表达式来匹配您想要的url。

    如果 url 中的 slug 值也不同,这个解决方案可能效果不佳,但在大多数情况下,这个解决方案可以正常工作。

    我写了一篇博文,讲述如何使用 RoutablePageMixin 使页面可路由,如果您想了解更多有关 RoutablePageMixin 的信息,可以查看此链接。

    Routable Page

    【讨论】:

    • 请注意,如果您想宣传自己的产品/博客,您必须披露您的隶属关系,否则您的回答可能会被标记为垃圾邮件。请阅读How to not be a spammer
    【解决方案2】:

    与其将您的新闻文章视为一种或多种产品的子对象,不如将它们视为按产品分类的一大群新闻文章可能会有所帮助。然后,您的产品页面将有效地成为新闻文章的过滤索引页面。

    我是这样建模的:

    • 如果您希望新闻文章存在于独立于任何特定类别的规范 URL,或者您希望使用页面审核和/或预览,则将 NewsArticle 定义为页面模型;否则,将其定义为 sn-p 或 ModelAdmin-managed 模型。
    • 在 NewsArticle 模型上,有一个 InlinePanel,编辑者可以在其中根据需要关联尽可能多的相关产品:

      class NewsArticle(Page):
          body = RichTextField()
          date = models.DateField()
      
          content_panels = Page.content_panels + [
              FieldPanel('body'),
              FieldPanel('date'),
              InlinePanel('related_products', label="Related products"),
          ]
      
      class NewsArticleRelatedProduct(Orderable):
          news_article = ParentalKey(NewsArticle, related_name='related_products')
          product = models.ForeignKey(ProductPage, on_delete=models.CASCADE, related_name='news_articles')
      
          panels = [
              PageChooserPanel('product'),
          ]
      
    • 在您的 ProductPage 模型上,添加一个返回新闻项目查询集的方法,并进行适当的过滤和排序:

      class ProductPage(Page):
          # ...
          def get_news_articles(self):
              return self.news_articles.live().order_by('-date')
      

    然后,您可以使用{% for news_article in page.get_news_articles %} 之类的标签循环浏览产品页面模板中的新闻文章。

    【讨论】:

    • 我喜欢倒置的想法,给了我一些思考的想法。感谢您的思想转变!
    猜你喜欢
    • 2023-04-02
    • 2014-03-06
    • 1970-01-01
    • 2016-04-28
    • 1970-01-01
    • 1970-01-01
    • 2017-07-28
    • 1970-01-01
    • 2019-03-09
    相关资源
    最近更新 更多