digitalfabrik / integreat-cms

Simplified content management back end for the Integreat App - a multilingual information platform for newcomers
https://digitalfabrik.github.io/integreat-cms/
Apache License 2.0
56 stars 35 forks source link

Add a region link replacement function #1851

Closed svenseeberg closed 1 year ago

svenseeberg commented 1 year ago

Motivation

Sometimes we rename or copy regions. In these cases the links in the content are not changed and point to the source or no longer existent region. Also the link status should be reset. That means the checker needs to check the link first, before we show a status.

Proposed Solution

Add a feature that allows to easily replace links to suit a newly created or rename region. This can probably be located near the Broken Link Checker in the GUI.

This function should only be available to expert users.

Alternatives

We currently use the following code in the Django shell to manually solve this problem:

from copy import deepcopy
from integreat_cms.cms.models import *
from linkcheck.models import *
from linkcheck import update_lock
from lxml.html import rewrite_links
from functools import partial

def replace_link(old_url, new_url, link):
    if link == old_url:
        return new_url
    return link

with update_lock:
    all_pages = Region.objects.filter(slug='deutschlandvorlage').first().pages.all()
    for page in all_pages:
        for language in page.languages:
            trans = page.get_translation(language.slug).latest_version
            if trans is None:
                continue
            trans_new = deepcopy(trans)
            changed = False
            for link in Link.objects.filter(object_id=trans.id):
                if str(link.url).startswith("https://integreat.app/deutschlandvorlage-textlab/"):
                    print(link.url)
                    fixed_url = str(link.url).replace("https://integreat.app/deutschlandvorlage-textlab/", "https://integreat.app/deutschlandvorlage/")
                    trans_new.content = rewrite_links(
                        trans_new.content,
                        partial(replace_link, link.url.url, fixed_url),
                    )
                    link.delete()
                    changed = True
            if changed:
                trans_new.id = None
                trans_new.version = trans.version + 1
                trans_new.minor_edit = True
                trans_new.save()

Additional Context

We also want a string replacement function (#1382). But it is probably safer to implement this first.

Design Requirements

svenseeberg commented 1 year ago

https://github.com/digitalfabrik/integreat-cms/issues/1383 is even more relevant, I guess.

timobrembeck commented 1 year ago

The utility function introduced in #2126 could be used for this as well, so I suggest to wait until that PR is merged before working on this issue. Edit: It is now