diff --git a/books/models.py b/books/models.py index 5fad9b57b..68a1d4c57 100644 --- a/books/models.py +++ b/books/models.py @@ -1183,7 +1183,7 @@ def books(self): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] subpage_types = ['books.Book'] max_count = 1 diff --git a/news/models.py b/news/models.py index 905a56d24..470e82df8 100644 --- a/news/models.py +++ b/news/models.py @@ -185,7 +185,7 @@ class NewsIndex(Page): ] subpage_types = ['news.NewsArticle'] - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 def get_url_parts(self, *args, **kwargs): @@ -621,7 +621,7 @@ def releases(self): ] subpage_types = ['news.PressRelease'] - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 diff --git a/pages/management/commands/restructure_root_page.py b/pages/management/commands/restructure_root_page.py new file mode 100644 index 000000000..a864e9a5d --- /dev/null +++ b/pages/management/commands/restructure_root_page.py @@ -0,0 +1,54 @@ +from django.core.management.base import BaseCommand +from wagtail.models import Page, Site +from pages.models import HomePage, RootPage + +class Command(BaseCommand): + help = ( + "Move children of HomePage to RootPage, elevate RootPage to site root, and delete HomePage.\n" + "⚠️ DRY RUN BY DEFAULT — use --commit to make changes." + ) + + def add_arguments(self, parser): + parser.add_argument( + '--commit', + action='store_true', + help="Apply the changes. Without this flag, the command runs in dry-run mode.", + ) + + def handle(self, *args, **options): + commit = options['commit'] + + old_home = HomePage.objects.first() + new_root = RootPage.objects.first() + + if not old_home or not new_root: + self.stderr.write(self.style.ERROR("Missing HomePage or RootPage instance.")) + return + + self.stdout.write(self.style.WARNING( + f"{'[COMMIT MODE]' if commit else '[DRY RUN]'} Starting restructure..." + )) + + # Move children of HomePage (except RootPage) under RootPage + for child in old_home.get_children().exclude(id=new_root.id): + self.stdout.write(f" - Would move {child.title} (ID: {child.id}) under RootPage") + if commit: + child.move(new_root, pos='last-child') + + # Move RootPage to root + wagtail_root = Page.get_first_root_node() + self.stdout.write(f" - Would move RootPage (ID: {new_root.id}) to be child of root") + if commit: + new_root.move(wagtail_root, pos='last-child') + + # Update Site root + site = Site.objects.get(is_default_site=True) + self.stdout.write(f" - Would set Site.root_page to RootPage (ID: {new_root.id})") + if commit: + site.root_page = new_root + site.save() + + if commit: + self.stdout.write(self.style.SUCCESS("✅ Restructure complete. Site root updated.")) + else: + self.stdout.write(self.style.WARNING("Dry run complete. No changes were made.")) diff --git a/pages/models.py b/pages/models.py index 98c1161ee..41d4b51da 100644 --- a/pages/models.py +++ b/pages/models.py @@ -210,7 +210,6 @@ class RootPage(Page): # TODO: we are allowing this to be built as a child of the homepage. Not ideal. # Once the home page is released, use something to migrate homepage children to root page and remove this parent type. parent_page_types = ['wagtailcore.Page', 'pages.HomePage'] - subpage_types = ['pages.FlexPage'] # which might also require allowing all pages to be children. def __str__(self): return self.path @@ -345,7 +344,7 @@ def get_where_map(self): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -898,7 +897,7 @@ class Meta: max_count = 1 template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] subpage_types = ['pages.K12Subject'] @@ -945,7 +944,7 @@ class ContactUs(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1069,7 +1068,7 @@ class Supporters(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1195,7 +1194,7 @@ def get_section_2_image_2(self): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1267,7 +1266,7 @@ class Give(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1307,7 +1306,7 @@ class TermsOfService(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1351,7 +1350,7 @@ class FAQ(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] class GiveForm(Page): @@ -1387,7 +1386,7 @@ class GiveForm(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1427,7 +1426,7 @@ class Accessibility(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1467,7 +1466,7 @@ class Licensing(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1547,7 +1546,7 @@ class Technology(Page): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1599,7 +1598,7 @@ class ErrataList(Page): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 def get_sitemap_urls(self, request=None): @@ -1642,7 +1641,7 @@ class PrivacyPolicy(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1699,7 +1698,7 @@ class PrintOrder(Page): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1840,7 +1839,7 @@ class LearningResearchPage(Page): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -1879,7 +1878,7 @@ class Careers(Page): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -2750,7 +2749,7 @@ def webinars(self): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -2851,7 +2850,7 @@ def get_url_parts(self, *args, **kwargs): template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] subpage_types = ['pages.Subject'] max_count = 1 @@ -3091,7 +3090,7 @@ class FormHeadings(Page): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] max_count = 1 @@ -3371,7 +3370,7 @@ class AllyLogos(Page): ] template = 'page.html' - parent_page_types = ['pages.HomePage'] + parent_page_types = ['pages.HomePage', 'pages.RootPage'] class Assignable(Page):