외부 URL용 리다이렉트 페이지

안녕하세요! 모든 외부 링크(필터링이 불가능하다면 모든 링크)를 예를 들어 exit.website.tld/?page={{URL}}으로 리디렉션하고 싶습니다.
Discourse에서 이것이 가능한가요? 만약 불가능하다면, 이를 위한 플러그인이 있나요? 검색을 해봤지만 제가 사용한 검색어로는 찾을 수 없었습니다.
Steam이 하는 방식과 유사하게 말입니다. (예시)

나도 이 문제에 대해 생각해 보고 있었습니다. 모든 외부 링크에 Internet Archive의 저장 URL을 붙이고 싶은데, 솔직히 말하면 카테고리별로 설정할 수 있으면 좋겠습니다.

플러그인을 통해 어떤 필터 기능을 구현할 수 있을 것 같긴 하지만, 테마 구성 요소로 데이터 조작 규칙을 유연하게 다루는 사례들도 있어서, 만약 현재 이것이 불가능하다면 여러분은 어떻게 접근하시겠습니까: 플러그인인가요, 아니면 테마 구성 요소인가요?

이것은 다소 사용자 비호적(user-hostile)인 기능이라고 봅니다(‘포럼 서명’ 같은 맥락이죠). 따라서 플러그인으로 구현되어야 할 것 같습니다. 테마 컴포넌트로 구현할 수 있을지는 잘 모르겠네요.

이전에 안전성 맥락에서 이 요청을 본 적이 있는데, 예를 들면

:scream: 아이고! 하이퍼링크를 통해 웹사이트로 이동하려고 합니다! 엄청난 위험에 대비하셨나요?!?

이런 식이었죠. 아주 드문 컨텍스트에서, 아주 드문 커뮤니티에서는 그럴 수 있을지도 모르겠네요.. 음.. 그렇겠죠?

저는 웹사이트를 아카이브하는 카테고리를 운영하고 있습니다. 저희 사용 사례는 아주 구체적이거나, 좀 게으른(?) 방식입니다. :slight_smile:

그리고 웹 아카이브 프록시는 메시지 안의 이미지 카피를 받는 것과 비슷하다고 생각합니다. 하지만 다시 말하지만, 저는 웹사이트를 아카이브하는 카테고리를 운영하는 사람입니다. :nerd_face:

공정하게 말해서, 타당한 사용 사례가 있을 수도 있겠지만, 나는 그냥 여기서 유저들을 위해 싸우고 있는 거지, 형…

제 생각에는 실제로 안전 관련 문제일 수 있습니다. 물론 여기 디스코र्स 메타 포럼이나 일부 프로그래밍 포럼에서는 사람들이 URL 등을 구별하는 방법을 알고 있지만, 기술에 초점을 두지 않는 포럼(특히 비기술 직종, 학교 관련 포럼 등)에서는 많은 사람들이 동일한 것처럼 보이지만 TLD가 다른 사이트나 심지어 완전히 다른 도메인 이름의 사이트에 접속하고 있다는 사실을 알아차리지 못할 수 있습니다.
물론 일부 포럼에서는 이것이 사용자 친화적이지 않을 수 있지만, 기본적으로 활성화되어야 한다는 말은 아무도 하지 않았습니다. 체크박스 형태로 만들어서 디스코र्स 자체의 페이지를 사용하거나 커스텀 페이지를 직접 링크하도록 할 수 있습니다.
제 생각에는 이것이 디스코스에 직접 포함되어야 할 필수적인 기능이지만, 물론 이것은 제 개인적인 의견일 뿐입니다.

Jeff는 이것이 플러그인으로 만들어져야 한다고 명확히 밝혔습니다(테마로 구현할 수 있다면 그쪽이 더 가능성이 높아 보이지만요). 과거 사례를 보면, 로그인 기능을 개발해 수백 개의 사이트가 이를 원하게 되고, 그중 수십 개의 엔터프라이즈 고객까지 포함된다면, 몇 년 안에 공식 플러그인으로 채택될 가능성이 높습니다.

하지만 테마로 구현할 수 있다면(그렇게 될 수 있다고 생각합니다) 논리적으로 따져 보면 discourse가 이미 해당 기능을 지원하고 있는 셈이며, 이를 구현하는 테마만 있으면 됩니다! 개발자를 위한 Discourse 테마 가이드를 확인하거나 Marketplace 채널에 예산을 명시하고 게시물을 올릴 수 있습니다. 제 추측으로는 최소 1,000달러는 들겠지만, 제 추측이 틀릴 수도 있습니다.

저는 디스코urs 테마 등에 대한 경험은 없지만, JS와 HTML에 대한 기본 경험은 있습니다. 이런 작업은 10~20분이면 충분할 텐데, 왜 1,000달러의 예산이 필요합니까?

20분 안에 할 수 있는 거라면 이미 했어야 했어요. 저는 아직 자바스크립트와 엠퍼를 잘 못 다루고 있어서, 생각보다 훨씬 쉽거나 할 수도 있겠네요. 제 생각엔 몇 시간 정도 걸릴 것 같아요.

테마 링크를 올려주세요! 기대가 됩니다.

약 5분 후, 작동하는 JS 코드를 만들었습니다 (아직 개선이 필요한 부분이 있지만, 작동합니다. 참고로 10줄짜리 코드입니다)
이제 찾아야 할 것은 페이지 로드 후 이 코드를 실행하는 방법뿐입니다…

대단해요! 이렇게 쉽다니 정말 다행이에요! 저한테는 그 작업이 정말 오랜 시간이 걸리거든요. 보통은 얼마나 걸려야 하는지 추정하는 데는 좀 더 능숙한 편이에요.

일반적으로 페이지가 Article Page인지 확인한 후, 모든 <article> 태그를 순회하면서 그 안에 포함된 실제 콘텐츠 태그를 찾습니다. 그런 다음 해당 태그 안의 모든 <a> 태그를 순회하면서, 그 href가 공식 사이트가 아닌지(이를 위해 기본적인 정규식을 사용합니다) 확인하고, 그렇지 않으면 Exit Page URL을 앞에 추가합니다.
하지만 아직 페이지가 로드되고 모든 동적 콘텐츠(예: 게시물)가 로드된 이후에 JS 코드를 실행하는 방법을 찾는 데 어려움을 겪고 있습니다. 임시 해결책으로 1~2초 후에 코드를 실행하는 방법이 있지만, 이는 그렇게 좋은 방법은 아니며, 일부 사용자에게는 로딩에 그보다 더 많은 시간이 걸릴 수도 있습니다…

테마 컴포넌트로 구현하는 것도 분명히 가능합니다. 하지만 크롤러 뷰에도 영향을 미치려면 플러그인으로 만들어야 한다는 점을 염두에 두세요.

찾고 계신 것은 포스트 데코레이터(post decorator)입니다. 이는 각 포스트가 렌더링되기 전에 스크립트를 실행할 수 있게 해주는 훅(hook)입니다. 플러그인 API의 일부입니다.

이제, 사용자가 하려는 것(모든 외부 링크를 리디렉션하는 것)에 대해 말씀드리자면, 그렇게 많은 마찰(friction)을 추가하는 것은 좋은 아이디어가 아니라고 생각하므로 그 부분으로는 도움을 드릴 수 없습니다. 게다가 그 부분은 이미 해결하신 것 같습니다. 다만, 게시물 내의 모든 외부 링크를 대상으로 설정을 만드는 방법에 대한 주석이 달린 예제를 여기에 공유합니다.

이것은 테마/테마 구성 요소의 header 섹션에 넣어야 합니다.

<script type="text/discourse-plugin" version="0.8">
  // 호스트 이름을 저장하여 재사용할 수 있도록 합니다.
  const siteHostname = location.hostname;
  
  // 모든 포스트에서 이를 수행하기 위해 데코레이터를 만들어 보겠습니다.
  api.decorateCooked(
    post => {
      // 포스트에 링크가 있나요?
      const links = [...post[0].querySelectorAll("a")];
      
      // 링크가 없으면 종료합니다.
      if (!links.length) return;
      
      // 링크가 있으므로, 필터링하여 외부 링크만 가져오겠습니다.
      const externalLinks = links.filter(
        link => link.hostname !== siteHostname
      );
      
      // 외부 링크가 있다면, 작업을 수행합니다. 예를 들어,
      // 각 외부 링크에 클래스를 추가할 수 있습니다.
      externalLinks.forEach(link => {
        link.classList.add('external-link');
        // 여기에 더 많은 작업을 수행합니다.
      });
    },
    // 메모리 누수를 방지하기 위해 데코레이터에 id를 부여합니다.
    { id: "external-link-decorator" }
  );
</script>

다시 말씀드리지만, 사용자를 리디렉션하는 것은 마찰이 너무 크고 금방 지루해질 것입니다. 따라서 외부 링크 옆에 은은한 아이콘을 추가하고 사용자에게 그 의미를 교육하는 등 다른 접근 방식을 고려해 보시는 것이 좋겠습니다.

이 사용 사례는 모든 링크된 웹사이트가 누군가가 클릭하든 하지 않든 적절히 보존되도록 보장하는 플러그인 또는 외부 통합(게시물 생성/편집 웹훅 사용)을 통해 훨씬 더 잘 처리될 수 있다고 생각합니다.