coderedcorp / coderedcorp/coderedcms

Make the Custom Navbar/Footer in Pro Template work in Multi-Site Installs

オープン
#683 コメント 1 件 リアクション 0 件 担当者 0 名 GitHub で見る
Type: Enhancement
主要言語
Python
スター
765
フォーク
154
PR マージ指標
30日以内にマージされた PR はありません

説明

#### Is your feature request related to a problem? Please describe.

We receently implemented WagtailCRX, and noticed that wagtail's Navbar and Footer models in the basic template work in multi-site installations, but the custom Navbar and Footer models in the pro template do not (though you could fall back to wagtail's default models with `CRX_DISABLE_NAVBAR = False` and `CRX_DISABLE_FOOTER = False`).

#### Describe the solution you'd like

We implemented the following in our site, which allows us to use custom Navbar(s) and Footer(s) in our multi-site install. Because nulls are allowed, it won't cause errors on existing installs. In existing installs, though, the template tags as implemented below would cause the components to not be rendered (existing model instances would not associated with any site initially). To resolve this, we could:

- Modify the template tags to check for a setting before implementing their site checks so it won't disappear the navbars and footers in existing projects (falling back to current functionality if `CRX_USE_SITE_FIELD=False` for example)
- Or, just set the template tags to fall back to showing all Navbar(s) and Footer(s) if there are no site-specific results

Would a PR to update the pro template (and add relevant tests & updates to docs) be of interest? Any additional thoughts/recommendations?

This proposal would also resolve #673

---

models.py

```python
"""
Create or customize your page models here.
"""

from coderedcms.blocks import (
HTML_STREAMBLOCKS,
LAYOUT_STREAMBLOCKS,
BaseBlock,
BaseLinkBlock,
LinkStructValue,
)
from coderedcms.forms import CoderedFormField
from coderedcms.models import (
CoderedArticleIndexPage,
CoderedArticlePage,
CoderedEmail,
CoderedEventIndexPage,
CoderedEventOccurrence,
CoderedEventPage,
CoderedFormPage,
CoderedLocationIndexPage,
CoderedLocationPage,
CoderedWebPage,
)
from django.db import models
from modelcluster.fields import ParentalKey
from wagtail import blocks
from wagtail.admin.panels import FieldPanel
from wagtail.fields import StreamField
from wagtail.snippets.models import register_snippet

# Other models...

@register_snippet
class Navbar(models.Model):
"""Custom navigation bar / menu."""

class Meta:
"""Meta class for Navbar."""
verbose_name = "Navigation Bar"

name = models.CharField(
max_length=255,
)
content = StreamField(
[
("link", NavbarLinkBlock()),
("dropdown", NavbarDropdownBlock()),
],
use_json_field=True,
)

site = models.ForeignKey( # <-- New Field
"wagtailcore.Site",
on_delete=models.CASCADE,
related_name="navbars",
null=True,
blank=True,
)

panels = [
FieldPanel("name"),
FieldPanel("site"), # <-- New panel item
FieldPanel("content"),
]

def __str__(self) -> str:
return self.name

@register_snippet
class Footer(models.Model):
"""Custom footer for bottom of pages on the site."""

class Meta:
"""Meta class for Footer."""
verbose_name = "Footer"

name = models.CharField(
max_length=255,
)
content = StreamField(
LAYOUT_STREAMBLOCKS,
verbose_name="Content",
blank=True,
use_json_field=True,
)

site = models.ForeignKey( # <-- New Field
"wagtailcore.Site",
on_delete=models.CASCADE,
related_name="footers",
null=True,
blank=True,
)

panels = [
FieldPanel("name"),
FieldPanel("site"), # <-- New panel item
FieldPanel("content"),
]

def __str__(self) -> str:
return self.name
```

Updated template tags render the navbar(s) and footer(s) for the current site:

website_tags.py

```python
"""Custom template tags for the website app."""
from django import template
from wagtail.models import Site
from website.models import Footer, Navbar

register = template.Library()

@register.simple_tag(takes_context=True)
def get_website_navbars(context):
"""Get the navbars for the current site.

Args:
context: The template context which contains the current request

Returns:
QuerySet: Navbar queryset filtered by the current site
"""
try:
# Get the current request from context
request = context['request']
# Get the current site from the request
current_site = Site.find_for_request(request)
# Return navbars associated with the current site
return Navbar.objects.filter(site=current_site)
except (KeyError, AttributeError):
# Fallback to returning all navbars if we can't determine the current site
return Navbar.objects.all()

@register.simple_tag(takes_context=True)
def get_website_footers(context):
"""Get the footers for the current site.

Args:
context: The template context which contains the current request

Returns:
QuerySet: Footer queryset filtered by the current site
"""
try:
# Get the current request from context
request = context['request']
# Get the current site from the request
current_site = Site.find_for_request(request)
# Return footers associated with the current site
return Footer.objects.filter(site=current_site)
except (KeyError, AttributeError):
# Fallback to returning all footers if we can't determine the current site
return Footer.objects.all()
```

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

調査の方向性

まず models.py のカスタム Navbar および Footer 定義と、website_tags.py のレンダリング関数を確認し、次に既存の pro template テストとドキュメントを調査します。サイト固有の結果と既存の未割り当てインスタンスがどのように動作すべきかを定義し、必要なマイグレーションとカバレッジを追加して、マルチサイトコンポーネントが既存のインストールを壊さずに正しくレンダリングされるようになったらドキュメントを更新します。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
django, python
領域
backend, frontend
issue の種類
機能追加
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。