Wagtail Redirects - Allow non Wagtail pages

422 views
Skip to first unread message

Chad Saunders

unread,
Aug 18, 2015, 10:58:02 AM8/18/15
to Wagtail support
Is there a way to get Wagtail to allow redirects to other pages on our site that do not "live" inside Wagtail?  We don't want to put our domain name in the redirect either.  We'd like them to all be relative.

Brett Grace

unread,
Aug 18, 2015, 11:55:57 AM8/18/15
to Wagtail support
The admin area is doing validation on the URL field, and it expects a fully qualified URL:

# https://github.com/torchbox/wagtail/blob/master/wagtail/wagtailredirects/models.py

class Redirect(models.Model):
   
old_path = models.CharField(verbose_name=_("Redirect from"), max_length=255, unique=True, db_index=True)
    site
= models.ForeignKey('wagtailcore.Site', verbose_name=_('Site'), null=True, blank=True, related_name='redirects', db_index=True, editable=False)
    is_permanent
= models.BooleanField(verbose_name=_("Permanent"), default=True, help_text=_("Recommended. Permanent redirects ensure search engines forget the old page (the 'Redirect from') and index the new page instead."))
    redirect_page
= models.ForeignKey('wagtailcore.Page', verbose_name=_("Redirect to a page"), null=True, blank=True)
    redirect_link
= models.URLField(verbose_name=_("Redirect to any URL"), blank=True)
                           
^^^^^^^^

See Django #10896,
UrlField cannot be used with relative URLs
https://code.djangoproject.com/ticket/10896
 


You can, of course, bypass this validation to achieve the affect you want (but there may be undesirable secondary effects). Example:

# Used Wagtail->Settings->Redirects to create a redirect from '/foo' to 'http://www.example.com/bar'

In [35]: Redirect.objects.all()
Out[35]: [<Redirect: Redirect object>]
In [36]: redirect = Redirect.objects.all()[0]
In [37]: redirect.old_path
Out[37]: '/foo'
In [38]: redirect.redirect_link
Out[38]: 'http://www.example.com/bar'
In [39]: redirect.redirect_link = "/bar"
In [40]: redirect.save()

# The site now redirects /foo to /bar (not to http://www.example.com/bar)

So a couple of ideas, assuming that you need this to be part of the UI and manipulating redirects in the backend is not feasible:

1) in theory you could write some sort of Django signal to intercept when Redirect objects are saved and rewrite them to relative URLs. (ugly)
2) Or maybe you can do some sort of monkey patching of the class to skip the validation step. (monstrous)
3) Replace the Redirect Settings plug-in with your own one that is more flexible. Not sure how much work this would be. (tedious)

I guess I would do the 3rd one because I'm a fairly tedious person.

If your end users do not have an ongoing, continuous need to add redirects, I would definitely take a different approach. In general I try to handle redirects at the web server level first, then as middleware, then in urls.py. So I would just do a bulk creation of Redirect objects from a CSV or Excel file.
Reply all
Reply to author
Forward
0 new messages