Página de redirección para URLs externas

¡Hola! Me gustaría redirigir todos los enlaces externos (o, si no es posible filtrar, todos los enlaces) a, por ejemplo, exit.website.tld/?page={{URL}}. ¿Es esto posible con Discourse? Si no, ¿existe un plugin para ello? Ya busqué pero no encontré ninguno con las consultas de búsqueda que utilicé.
Es decir, algo similar a lo que hace Steam. (Ejemplo)

Yo también lo había estado pensando; quería agregar la URL de guardado de Internet Archive a todos los enlaces externos, y seamos honestos: sería genial poder configurarlo por categoría.

Pienso que hay algún tipo de filtro que podría hacerse mediante un plugin, pero la gente hace cosas con componentes del tema que parecen doblar las reglas de manipulación de datos, así que si esto no es posible actualmente, ¿cómo abordarían su implementación: mediante un plugin o un componente del tema?

Vemos esto como una característica algo hostil para el usuario (similar a las «firmas de foro»), por lo que tendría que ser un plugin. No estoy seguro de si podría implementarse en un componente de tema.

He visto esta solicitud antes en el contexto de la seguridad, como en

:scream: ¡oh no! ¡estás a punto de visitar un HIPERVÍNCULO a un SITIO WEB! ¿Te has preparado para un PELIGRO INCREÍBLE?!?!

y supongo que podría tener sentido en algunos contextos extremadamente raros en algunas comunidades extremadamente raras… eh… supongo.

Administro una categoría para archivar sitios web. Nuestro caso de uso es súper específico y perezoso. :slight_smile:

Además, considero que el proxy de archivo web es similar a guardar una copia de una imagen en un mensaje, pero de nuevo, administro una categoría para archivar sitios web. :nerd_face:

Es justo, puede haber algunos casos de uso válidos, pero aquí estoy luchando por los usuarios, hombre…

En mi opinión, en realidad podría tratarse de un asunto de seguridad, porque, por supuesto, aquí en el Foro Meta de Discourse o en algunos Foros de Programación la gente sabe diferenciar las URL, etc., pero en Foros que no están tan centrados en la tecnología (especialmente Foros para trabajos no técnicos, escuelas, etc.), muchas personas podrían no darse cuenta de si están en un sitio que se ve igual pero tiene una TLD diferente o incluso un Nombre de Dominio completamente distinto.
Y aunque esto, por supuesto, puede ser hostil para el usuario en algunos Foros, nadie dice que deba estar habilitado de forma predeterminada. Podrías simplemente hacerlo como una casilla de verificación que luego usaría una página del propio Discourse o enlazaría directamente a una página personalizada.
En mi opinión, esto es más bien una característica esencial que debería estar directamente en Discourse, pero, por supuesto, esa es solo mi propia opinión.

Jeff ha dejado claro que esto tendrá que ser un plugin (a menos que pueda hacerse en un tema, lo cual parece probable). La historia sugiere que si desarrollas el inicio de sesión y cientos de sitios lo desean, incluidos docenas de clientes empresariales, debería convertirse en un plugin oficial en solo unos pocos años.

Pero, si es posible hacerlo en un tema, lo cual creo que podría ser, entonces, en cierto modo, Discourse ya soporta la función; ¡solo necesitas un tema para implementarla! Puedes consultar la guía para desarrolladores de temas de Discourse o publicar en Marketplace con un presupuesto. Mi estimación es que cuesta al menos $1000, pero podría estar equivocado.

Aunque no tengo experiencia con Temas de Discourse, etc., tengo experiencia básica con JS y HTML. Algo como esto no debería tomar más de 10-20 minutos de trabajo. ¿Por qué se necesitaría un presupuesto de $1000?

Si puedes hacerlo en veinte minutos, entonces ya deberías haberlo hecho. Aún soy bastante malo con JavaScript y Ember, tal vez es mucho más fácil de lo que creo. Creo que lleva varias horas de trabajo.

¡Por favor, publica un enlace a tu tema! No puedo esperar a verlo.

Después de unos 5 minutos, conseguí un código JS funcional (que aún necesita algunas mejoras, pero funciona; por cierto, son 10 líneas).
Lo único que me falta averiguar ahora es cómo ejecutar este código después de cargar la página…

¡Genial! Me alegra que fuera tan fácil. Eso me lleva una cantidad de tiempo insana. Por lo general, soy mejor adivinando cuánto tiempo debería tomar.

En general, simplemente verifica si estás en una página de artículo, recorre todas las etiquetas <article>, encuentra la etiqueta real del contenido dentro de ellas, recorre todas las etiquetas <a> en su interior y, si su href no es un sitio oficial (usando una expresión regular básica para ello), añade la URL de la página de salida al principio.
Pero todavía tengo dificultades para averiguar cómo ejecutar el código JavaScript después de que la página se haya cargado y todo el contenido dinámico (como las publicaciones) se haya cargado. Una solución temporal sería ejecutar el código después de 1-2 segundos, pero eso no es muy bueno y para algunas personas podría tardar más que eso en cargarse…

Ciertamente se puede hacer como un componente de tema, pero ten en cuenta que tendrá que ser un complemento si quieres que también afecte a la vista del rastreador.

Lo que buscas se llama decorador de publicaciones. Es un gancho que te permite ejecutar scripts antes de que se renderice cada publicación. Es parte de la API de complementos.

Ahora, en cuanto a lo que quieres hacer (redirigir todos los enlaces externos). No creo que añadir tanta fricción sea una buena idea, así que no puedo ayudarte con eso; además, ya resolviste esa parte. Dicho esto, aquí tienes un ejemplo comentado de cómo puedes crear una configuración que apunte a todos los enlaces externos en las publicaciones.

Esto va en la sección header de tu tema o componente de tema:

<script type="text/discourse-plugin" version="0.8">
  // Almacena el nombre de host para poder reutilizarlo.
  const siteHostname = location.hostname;
  
  // Creemos un decorador para hacer esto en cada publicación
  api.decorateCooked(
    post => {
      // ¿La publicación tiene enlaces?
      const links = [...post[0].querySelectorAll("a")];
      
      // Sin enlaces, salimos.
      if (!links.length) return;
      
      // Tenemos enlaces, filtremoslos y tomemos solo los externos
      const externalLinks = links.filter(
        link => link.hostname !== siteHostname
      );
      
      // Si tenemos algunos enlaces externos, hagamos algo. Por ejemplo, podemos
      // añadir una clase a cada enlace externo así.
      externalLinks.forEach(link => {
        link.classList.add('external-link');
        // Haz más trabajo aquí.
      });
    },
    // Le damos un ID a nuestro decorador para evitar fugas de memoria.
    { id: "external-link-decorator" }
  );
</script>

De nuevo, redirigir a los usuarios es demasiada fricción y resultará molesto muy rápido. Así que consideraría otro enfoque, como añadir un icono sutil al lado de los enlaces externos y enseñar a tus usuarios qué significa, ¿qué te parece?

Creo que este caso de uso se beneficia mucho más de un plugin o una integración externa (usando un webhook de creación/edición de publicaciones) que garantice que todos los sitios vinculados se preserven adecuadamente, independientemente de si alguien hace clic en ellos o no.