Rediriger la catégorie vers une URL externe

Is there some native facility for redirecting categories to external URLs?

Customize >> Permalinks apparently does not support this use.

Why would you redirect a category to an external URL?
What’s the point of having the category if you only need a link?

To have the link displayed as a category without going through all the necessary CSS fiddling to do so without it simply being a category.

The community where I’ll be doing this has a few related Discourse installs that each deal with a different set of topics; I want to more cleanly link them together by creating ‘categories’ that link from each site to each other site.

I briefly looked at doing this and it came down to two alternatives.

  1. Create the category with read only permissions for everyone and put the link into the ‘About this category’ page, maybe including a short paragraph why, like an ‘official’ external support site.

  2. Target and overwrite the link href in a theme component.

I was afraid it would come down to that or doing a rewrite at the server level. I think I may just go with the (somewhat questionable) JavaScript option.

So, related issue: I’ve now implemented a redirect (using JavaScript), but… it works only on refresh, which is clearly suboptimal. At any rate, here’s the code I’m using:

$( document ).ready(function() {
	if ( window.location.href === "https://omnifora.com/c/redirect-politifora" ) {
		window.location.replace( "https://politifora.com/" );
	}
});

As should be obvious from the code, Omnifora is the primary site in this network and I am attempting to redirect a Politifora category on Omnifora to Politifora. I’ve already eliminated caching (browser, server, Cloudflare) as a potential culprit. Is there some quirk in Discourse that would cause this redirect not to trigger?

Yes, being a single-page-app the page only loads once, subsequent loads just replace the page contents. There is a page change API you can hook into:

I’m sure this is the right way to accomplish the redirect, but I am not sure how to write the necessary code. I’ve tried the following and neither seems to work:

api.onPageChange((url) => {
	var targeturl = 'https://politifora.com/';
	if ( url === '/c/redirect-politifora' ) {
		$(location).attr('href',targeturl);
	}
});

and

api.onPageChange((url) => {
	if ( url === '/c/redirect-politifora' ) {
		window.location.replace( 'https://politifora.com/' );
	}
});

if you wanted a redirect this is the way to do it

api.onPageChange((url) => {
	if (url.includes('/c/redirect-politifora')) {
		window.location.replace('https://politifora.com/');
	}
});

however this is kinda slow and won’t run until the page has finished loading, which means users will still see the redirect category. i tried a second way, which is using jQuery to replace the links on the index or anywhere else this category appears.

api.onPageChange(() => {
  $(function(){
    $('a[href*="/c/redirect-politifora').attr(
      'href', 'https://politifora.com/'
    ); 
  });
});

with this you don’t need a redirect, because it modifies href attribute of every redirect-politiflora link in place.

Perhaps I’m missing something, but I tried each of those solutions (both imported from an external .js and dropped in as a customization) and was unable to get either one to work.

where are you inserting them, and do you have the correct script tags around them

I tried both the header (using defer) and the footer (via Customize). When inserted via Customize, I had the code surrounded by <script></script> with type="text/discourse-plugin" set.

Update:

The window.location.replace option is currently live on Omnifora. I am using the following code (yes, I have tried a number of different matching options, but none of them seem to work):

Code Dropped into Customize

<script type="text/discourse-plugin" version="0.8.19">
api.onPageChange((url) => {
    if ( url === 'c/redirect/politifora' || url === '/c/redirect-politifora' || url === 'https://omnifora.com/c/redirect-politifora' || url.includes('/c/redirect-politifora') || url.match('/c/redirect/politifora') ) {
        window.location.replace('https://politifora.com/');
    }
});
</script>

Code as Rendered on Page

<script>Discourse._registerPluginCode('0.8.19', function (api) {

    api.onPageChange(function (url) {
        if (url === 'c/redirect/politifora' || url === '/c/redirect-politifora' || url === 'https://omnifora.com/c/redirect-politifora' || url.includes('/c/redirect-politifora') || url.match('/c/redirect/politifora')) {
            window.location.replace('https://politifora.com/');
        }
    });
});</script>

Given the wrapper that Discourse appears to have applied, it seems the code is partially working, but not performing its intended purpose (i.e., redirecting that category to Politifora). The live code (and its failure to function) can both be viewed on the aforementioned site (the target/affected category is currently at the bottom of the category list).

Is there some specific version of the API I should be using for this?

The following script achieves the intended result when added to </head> via Customize:

<script type="text/discourse-plugin" version="0.8.19">
api.onPageChange(() => {
	if ( window.location.href === "https://omnifora.com/c/redirect-politifora" ) {
		window.location.replace( "https://politifora.com/" );
	}
});
</script>

Merci pour cela ! J’avais besoin qu’un ensemble de sous-catégories en redirige une. Puisque mon Customize inclut déjà une vérification onPageChange() (utilisée pour afficher un en-tête uniquement sur la page d’accueil), cela devrait fonctionner également, et n’est donc pas codé en dur avec l’URL complète du site :

<script type="text/discourse-plugin" version="0.8.19">
api.onPageChange((url) => {
       // Vérifier si nous sommes sur la page d'accueil
        if (url === "/" || url === homeRoute) {
              // faire des choses personnalisées pour la page d'accueil
       } else if ( url=== "/c/redirect-politifora" ) {
             // redirection de catégorie
             window.location.replace( "https://politifora.com/" );
       } else {
             // faire des choses sur toutes les autres pages, si nécessaire
       }
});
</script>

En fait, je ne l’ai pas utilisé : c’était trop confus avec des délais excessifs, et le navigateur s’est redirigé vers une autre page alors que la sous-catégorie s’affichait. Mais bon, j’ai appris quelque chose.

Vous pourriez constater que c’est moins problématique si vous modifiez la route plutôt que de vous fier à api.onPageChange(), qui semble se déclencher après le rendu de la page.

Voir Redirect an existing route in a theme component