Skip to content

Using django contrib's Redirects #82

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
thijsdezoete opened this issue Nov 28, 2023 · 8 comments
Closed

Using django contrib's Redirects #82

thijsdezoete opened this issue Nov 28, 2023 · 8 comments

Comments

@thijsdezoete
Copy link

Hi there! Awesome project, I am a big fan!

However I would either like to know how I can contribute to support django's contrib Redirects in distill, or how to properly implement a redirect in a project.

I have tried a few options, but I still seem to get stuck and can't quite figure out where I'm going wrong:

Using a view function like so:

def provider_redirect_view(request, new_url):
    html = f'<html><head><meta http-equiv="refresh" content="0;url={new_url}" /></head><body></body></html>'
    return HttpResponse(html)

And then looping over all the redirects:

for redirect in Redirect.objects.all():
    print(f"Generating pattern for: {redirect.old_path}")
    unique_name = f"redirect_{redirect.id}"

    # Each tuple should match the arguments expected by the view
    def x_distill_func(new_url=redirect.new_path):
        return [(new_url,)]

    urlpatterns.append(
        distill_path(
            redirect.old_path.lstrip('/'),
            provider_redirect_view,
            name=unique_name,
            distill_func=x_distill_func
        )
    )

Any help is much appreciated, or any hints as to how I can proceed. All I'm really trying to do is have distill generate a small html file for each redirect with a refresh code to another url (following the django contrib redirect model old_path and new_path variables).

@meeb
Copy link
Owner

meeb commented Dec 6, 2023

Hi. I don't see anything wrong with the concept of your implementation but I've never tried to use contrib redirects with distill myself. The best way if you wanted to contribute would probably be to fork the repo then add a test case that verifies your implementation (adds some redirects, runs a distill and verifies the output files contain the expected content). The only thing I can think of from your code above is your usage of urlpatterns isn't modifying the correct global urlpatterns maybe?

I would suggest directly dropping in your distill_path(...) into the normal urls.py urlpatterns (with a dummy from/to path) and check that works as expected first, then expand on it from there.

You've not specifically stated what doesn't work. Does the filename.html with the meta redirect in it just not get generated?

@thijsdezoete
Copy link
Author

Hey @meeb

Thanks for your response! Right now I've solved it with the following management command and using this in a makefile to generate my entire site, however I think it should be possible to create something within Distill, but I'm a bit time-constrained right now. I'd love to contribute, and will create something as soon as I can.

For anyone reading along / running into the same issue, here is my (temporary) solution:
./management/commands/generate_redirects.py

from django.core.management.base import BaseCommand
from django.contrib.redirects.models import Redirect
from django.conf import settings
import os

class Command(BaseCommand):
    help = 'Generates static HTML files for redirects'

    def handle(self, *args, **kwargs):
        abspath = os.path.abspath(os.path.join(settings.DISTILL_DIR))
        print(f"Creating redirects in {abspath}")
        redirects = Redirect.objects.all()
        for redirect in redirects:
            redirect_path = redirect.old_path.lstrip('/')
            redirect_file = os.path.join(settings.DISTILL_DIR, redirect_path, 'index.html')
            os.makedirs(os.path.dirname(redirect_file), exist_ok=True)
            with open(redirect_file, 'w') as file:
                file.write(f'<html><head><meta http-equiv="refresh" content="0;url={redirect.new_path}" /></head><body></body></html>')
            self.stdout.write(self.style.SUCCESS(f'Successfully created redirect for {redirect.old_path}'))

@meeb
Copy link
Owner

meeb commented Dec 8, 2023

Thanks, if that works for you I can port it into distill easily enough. Cheers!

@icedogas
Copy link

icedogas commented Mar 30, 2024

Hi, for redirections, I have created a custom template with the following code:

<html>
    <head>
        <meta charset="UTF-8">
        <meta http-equiv="refresh" content="0;URL=https://yoururl.com/new" />
        <meta name="robots" content="noindex" />
    </head>
    <body></body>
</html>

This works well. However, for SEO purposes, it's necessary to use a 301 status code. It's better to implement this within the nginx, .htaccess, or in the Cloudflare settings, for example.

@thijsdezoete
Copy link
Author

@meeb let me know if this gets ported into the main branch/release! I'd love to update, specially with the better template from @icedogas

@meeb meeb closed this as completed in f8ef9cf May 24, 2024
@meeb
Copy link
Owner

meeb commented May 24, 2024

The above commit has added redirect support as a --generate-redirects additional flag to ./manage.py distill-local. This should do what you want. This writes the template as detailed here:

https://github.com/meeb/django-distill/blob/master/django_distill/renderer.py#L443

and has accompanying tests. I'll bundle this into the next release.

@thijsdezoete
Copy link
Author

Woah! that's awesome! Thank you! <3

@theangular

This comment has been minimized.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants