-
Notifications
You must be signed in to change notification settings - Fork 40
Switch Wagtail page‐type while keeping existing ID and Slug
Example scenario: The content team wants to convert a page originally created using a CustomPage template to a ResourcePage while maintaining the original page ID and slug to preserve Wagtail's existing internal links and references to the page.
This can be done for any page type, the example below uses the most common request of converting a CustomPage to a ResourcePage.
-
A content team member creates a draft page in Wagtail on production using the ResourcePage template (or whatever the new page type is). We will call this the "dummy page."
-
Important: Publish the draft dummy page temporarily and create a published copy of it in Wagtail. This copy will ultimately be the final page.
- Make sure to check the
publish checkbox
when creating your copy. - Make a note of your copied page's ID.
- Don't make any edits to your copied page in Wagtail as this will not work if the page has a revision history.
- Make sure to check the
- Unpublish the draft dummy page once you have created your published copy.
-
Important: Publish the draft dummy page temporarily and create a published copy of it in Wagtail. This copy will ultimately be the final page.
-
Log into CloudFoudry(CF) and access PSQL on production (TWO TERMINAL TABS)
FIRST TERMINAL TAB: # Log into CloudFoudry: cf login --sso # Target the environment you're exporting from cf target [-o <org name>] -s <space name> # Set app GUID cms_app_guid=$(cf app --guid cms) # Establish the tunnel for the SSH session tunnel=$(cf curl /v2/apps/$cms_app_guid/env \ | jq -r '[.system_env_json.VCAP_SERVICES."aws-rds"[0].credentials | .host, .port] | join(":")') # Check what PG services you are running locally and stop them brew services list brew services stop postgresql@[#] # Start the tunnel. Leave this window open. cf ssh -N -L 5432:$tunnel cms
SECOND TERMINAL TAB: # In the second terminal, set credentials and database name to connect cms_app_guid=$(cf app --guid cms) creds=$(cf curl /v2/apps/$cms_app_guid/env \ | jq -r '[.system_env_json.VCAP_SERVICES."aws-rds"[0].credentials | .username, .password] | join(":")') dbname=$(cf curl /v2/apps/$cms_app_guid/env \ | jq -r '.system_env_json.VCAP_SERVICES."aws-rds"[0].credentials | .name') # Connect to the database with PSQL psql postgres://$creds@localhost:5432/$dbname
Once your connected to the database with PSQL:
- End all commands with a semi-colon
- You can use ABORT; to get out of a sequence
- Make sure to COMMIT; each change
- The IDs used in this example:
- Original CustomPage ID (the ID we want to keep): 1234
- Your copy of dummy ResourcePage ID: 5678
- content_type_ids: CustomPage:30, ResourcePage:49 (Find others with
select * from django_content_type;
)
-
Delete the record from the
public.home_custompage
table for the original CustomPage ID:=> BEGIN; BEGIN => DELETE FROM public.home_custompage WHERE page_ptr_id=1234; DELETE 1 => COMMIT; COMMIT
-
Change that page's
content_type_id
inwagtailcore_page
table to a ResourcePage(49). Tip: You can see all content_type_ids by querying:select * from django_content_type;
=> BEGIN; BEGIN => update public.wagtailcore_page set content_type_id=49 where id=1234; UPDATE 1 => COMMIT; COMMIT
-
Change the
page_ptr_id
of your published copy to the originalpage_ptr_id
in thepublic.home_resourcepage
table :=> BEGIN; BEGIN => update public.home_resourcepage set page_ptr_id=1234 where page_ptr_id=5678; UPDATE 1 => COMMIT; COMMIT
-
The page has now been converted. View the page in a browser and make sure you can edit and save it in Wagtail*. Make sure you are testing the original ID, not the dummy or the dummy copy. Use an icognito window or a hard-refresh to avoid confusion of Wagtail caching. If all looks good, go on to step 7.
*If you get an error (500 Server Error) when trying to edit in Wagtail, you can try to fix this by going into the Django Python Shell (WIKI) and run:
page.save_revision().publish()
-
A little cleanup: Your copy of the dummy page(5678) now remains orphaned in
wagtailcore_page
table. Attempt to delete that record with the delete command below. If you get any errors due to foreign key constraints as shown in the example code below, you can remove them (step 8) and then repeat the delete command, hopefully without errors. Likely foreign key constraints errors are forwagtailcore_pagesubscription
orwagtailcore_revision
.=> BEGIN; BEGIN; => DELETE FROM public.wagtailcore_page WHERE id=5678; DELETE 1 => COMMIT; COMMIT ERROR: update or delete on table "wagtailcore_page" violates foreign key constraint "wagtailcore_pagesubs_page_id_a085e7a6_fk_wagtailco" on table "wagtailcore_pagesubscription" DETAIL: Key (id)=(5678) is still referenced from table "wagtailcore_pagesubscription".
-
Delete foreign key constraints and then repeat step 7 to delete the record without error. Tip: for
wagtailcore_pagesubscription table
the page is referenced bypage_id
, forwagtailcore_revision table
it is referenced byobject_id
(in quotes)=> BEGIN; BEGIN; => DELETE FROM public.wagtailcore_pagesubscription WHERE page_id=5678; DELETE 1 => COMMIT; COMMIT
-
Ask content team to verify that the new page looks correct and ask them to delete their dummy page in Wagtail.
-
Search.gov indexing of temporarily published pages: When you temporarily publish a copy of a page for this process, it automatically becomes part of the
/sitemap-wagtail.xml
. Search.gov indexes our sitemap about every two hours. So If that page happens to still be published when search.gov kicks off indexing, it will be added to the index and will show up in site-search results. While un-publishing the page removes it from sitemap, it does not remove it from the index. It takes about a month for un-published pages to drop off the index. Content editors often test the searchability of pages after making changes, and may report that there is an unwanted search-result for one of the temporary pages. If you do not want to wait a month for it to drop off, you can email search.gov to have it removed immediately (WIKI). -
Wagtail admin search duplicates: The page converted in the process in this WIKI may be listed twice in search results when searching in the Wagtail admin (It does NOT show up twice in the admin explorer listing, just admin search results). While this is a harmless side effect of this process, sometimes this is bothersome to content editors. You can solve this by removing the duplicate entry that has the
old content_type
in thewagtailsearch_indexentry
table. Important: Make sure you are deleting the one with theold content_type
. (An alternate option that might solve this problem is:./manage.py update_index
, but that has not been tested. If you test it and it works, please update this Wiki.)DELETE FROM public.wagtailsearch_indexentry WHERE object_id='1234' AND content_type_id=30;