diff --git a/coderedcms/migrations/0043_remove_coderedpage_struct_org_actions_and_more.py b/coderedcms/migrations/0043_remove_coderedpage_struct_org_actions_and_more.py new file mode 100644 index 00000000..27f4733f --- /dev/null +++ b/coderedcms/migrations/0043_remove_coderedpage_struct_org_actions_and_more.py @@ -0,0 +1,156 @@ +# Generated by Django 4.2.16 on 2025-02-06 22:18 + +from django.db import migrations, models +import django.db.models.deletion +from wagtail.images import get_image_model_string + + +STRUCT_ORG_FIELDS = [ + "struct_org_type", + "struct_org_name", + "struct_org_logo_id", + "struct_org_image_id", + "struct_org_phone", + "struct_org_address_street", + "struct_org_address_locality", + "struct_org_address_region", + "struct_org_address_postal", + "struct_org_address_country", + "struct_org_geo_lat", + "struct_org_geo_lng", + "struct_org_hours", + "struct_org_actions", + "struct_org_extra_json", +] + + +def copy_struct_org(apps, schema_editor): + """ + Copy struct org data from each site's Root Page to the site's + settings. + """ + + SeoSettings = apps.get_model("wagtailseo", "SeoSettings") + Site = apps.get_model("wagtailcore", "Site") + + for site in Site.objects.all().select_related("root_page"): + # We are assuming that all pages in coderedcms inherit from + # ``CoderedPage``, which is what contains the SEO data. If the + # root page is not a CoderedPage, then simply skip it as it + # will likely be the site owner's reponsibility to handle this + # migration manually. + if not hasattr(site.root_page, "coderedpage"): + return + page = site.root_page.coderedpage + seo_settings, _ = SeoSettings.objects.get_or_create(site=site) + for field in STRUCT_ORG_FIELDS: + print(f"Copy {page.title} : {field}") + setattr(seo_settings, field, getattr(page, field)) + seo_settings.save() + + +def reverse_struct_org(apps, schema_editor): + """ + The reverse migration. + + For every site, find the most top-level page inheriting from SeoMixin + and fill its struct information using the site's settings + """ + SeoSettings = apps.get_model("wagtailseo", "SeoSettings") + for seo_settings in SeoSettings.objects.all().select_related( + "site", "site__root_page" + ): + page = seo_setting.site.root_page + if not hasattr(page, "coderedpage"): + return + cr_page = page.coderedpage + for field in STRUCT_ORG_FIELDS: + setattr(cr_page, field, getattr(seo_settings, field)) + cr_page.save() + + +class Migration(migrations.Migration): + dependencies = [ + ("wagtailimages", "0027_image_description"), + ("coderedcms", "0042_remove_coderedsessionformsubmission_thumbnails_by_path"), + ("wagtailseo", "0003_seosettings_struct_org_fields"), + ] + + operations = [ + migrations.RunPython( + copy_struct_org, reverse_struct_org + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_actions", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_address_country", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_address_locality", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_address_postal", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_address_region", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_address_street", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_extra_json", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_geo_lat", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_geo_lng", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_hours", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_image", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_logo", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_name", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_phone", + ), + migrations.RemoveField( + model_name="coderedpage", + name="struct_org_type", + ), + migrations.AlterField( + model_name="coderedpage", + name="og_image", + field=models.ForeignKey( + blank=True, + help_text="Shown when linking to this page on social media. If blank, may show an image from the page, or the default from Settings > SEO.", + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to=get_image_model_string(), + verbose_name="Preview image", + ), + ), + ] diff --git a/coderedcms/models/page_models.py b/coderedcms/models/page_models.py index e7f95039..7480ef2d 100755 --- a/coderedcms/models/page_models.py +++ b/coderedcms/models/page_models.py @@ -363,7 +363,7 @@ class Meta: ), ] - promote_panels = SeoMixin.seo_meta_panels + SeoMixin.seo_struct_panels + promote_panels = SeoMixin.seo_meta_panels settings_panels = Page.settings_panels + [ FieldPanel("content_walls"), @@ -1613,6 +1613,7 @@ def data_to_dict(self, processed_data, request): preview_modes = [ ("form", _("Form")), ("landing", _("Thank you page")), + ("wagtail-seo", _("SEO Preview")), ] def serve_preview(self, request, mode): diff --git a/coderedcms/templates/coderedcms/pages/base.html b/coderedcms/templates/coderedcms/pages/base.html index de5f4c6a..f3cf7cb3 100755 --- a/coderedcms/templates/coderedcms/pages/base.html +++ b/coderedcms/templates/coderedcms/pages/base.html @@ -183,6 +183,7 @@

{% trans "Related" %}

{% block struct_seo %} {% include "wagtailseo/struct_data.html" %} + {% include "wagtailseo/struct_org_data.html" %} {% block struct_seo_extra %}{% endblock %} {% endblock %} diff --git a/pyproject.toml b/pyproject.toml index 55f8fb39..b06bc03f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -41,7 +41,7 @@ dependencies = [ "wagtail>=6.3,<7.0", "wagtail-cache>=2.4,<3", "wagtail-flexible-forms==2.*", - "wagtail-seo>=2.5,<3", + "wagtail-seo==3.*", ] description = "Wagtail + CodeRed Extensions enabling rapid development of marketing-focused websites." dynamic = ["version"]