TOC 컴포넌트 및 헤더 ID

TOC(목차) 컴포넌트는 헤더 텍스트를 기반으로 헤더 요소의 id 속성을 생성합니다.

예를 들어 아래 헤더가 있습니다.

main outlet

여백은 #main-outlet에 적용된 스타일에서 비롯됩니다. #main-outlet은 이 게시물과는 아무런 관련이 없는 Discourse 앱 요소입니다.

만약 헤더에 대안 id를 지정할 수 있다면 큰 문제는 아닙니다. TOC 컴포넌트는 이를 지원합니다:

https://github.com/discourse/DiscoTOC/blob/master/common/header.html#L293

불행히도, Discourse는 위의 코드가 실행되기 전에 게시물 요소에서 id 속성을 제거하므로 해당 로직이 무력화됩니다.

<h4 id="alt-main-outlet">main outlet</h4>를 사용하는 헤더의 예를 들면:

main outlet

alt-main-outlet이 아닌 여전히 main-outlet을 사용하고 있습니다.

Discourse가 누군가가 페이지 요소를 해킹하는 것을 예상하고 이렇게 하는 것 같습니다. 하지만 TOC 컴포넌트를 사용하면 이를 우회하는 것이 충분히 쉽습니다.

이 문제에 대한 해결책이 있거나, 제가 놓친 잘 논의된 문제라면, 뒤에 이어질 자발적인 의견에 대해 사과드립니다 :slight_smile:


P.S.

개인적으로 Discourse가 요소의 id 속성을 제거해서는 안 된다고 생각합니다. 이는 웹 페이지의 근본적인 구성 요소이며, URL 단편(fragment)을 통한 페이지 내비게이션에 사용됩니다. 누군가 게시물 내 요소로 링크를 만들고자 한다면, 저는 그것이 저자로서의 권리라고 생각합니다.

TOC가 ID 해킹을 가능하게 한다는 사실은, 애초에 ID를 제거하는 이 조치가 잠재적으로 폐기될 수 있음을 시사합니다.

Discourse 팀이 ID 하이재킹에 대해 그 정도로 우려한다면, 모든 Discourse ID에 접두사를 붙여야 합니다(예: discourse-main-outlet). 그리고 ID 제거는 이러한 접두사가 붙은 ID에만 적용되어야 합니다.

기존 코드를 고려할 때 이것이 불가능하다는 점은 이해합니다!

제거되는 제외 ID 목록(예: main-outlet 등)을 상상해 볼 수 있습니다. 이는 여전히 TOC가 이 안전 장치를 우회하는 문제를 남기지만, 적어도 저자들이 유용한 앵커를 만들 수 있게 해줍니다.


P.P.S.

이와 직접적으로 관련되는 문제는 동일한 텍스트 페이로드를 가진 헤더입니다.

Topic One

Examples

Topic Two

Examples

TOC를 사용하면 두 개의 Examples 헤더 모두 동일한 ID를 받게 되며, 이는 명백히 깨진 상태입니다. TOC는 증가하는 인덱스를 추가할 수 있습니다(예: examples, examples-2 등) — 그리고 기본적으로 그렇게 해야 합니다 — 하지만 여전히 더 나은 해결책은 위에서 논의된 문제, 즉 저자들이 콘텐츠 설명 방식을 결정할 수 있게 해주는 것입니다. 예: <h5 id="topic-one-examples">Examples</h5> 등.

@Johani 이거 어떻게 생각해?

헤더를 추가해야 한다면 heading-- 접두사가 필요합니다. 이에 대한 자세한 정보는 여기서 확인하실 수 있습니다: Linking to a heading within a post or topic

이러한 접두사가 없는 id는 id 값과 관계없이 모두 제거됩니다.

중복된 텍스트를 가진 헤더는 현재 TOC 구성 요소에서 지원되지 않으며, 과거에도 지원된 적이 없습니다. 해당 구성 요소는 헤더의 텍스트를 기반으로 id를 생성합니다. 따라서 텍스트가 완전히 동일한 두 개의 헤더는 동일한 id를 부여받게 됩니다.

현재 해당 구성 요소에서 이 문제를 패치할 계획은 없습니다. 자동 id 생성은 다음 버전의 Discourse 기능 목록에 포함되어 있으며, 헤더의 인덱스를 id에 추가하여 중복 헤더 문제를 해결할 계획입니다.

이를 코어에 구현할 때, 생성된 헤더에 접두사를 추가하는 것만으로도 충분할 것이라고 생각합니다.

상당히 합리적인 설명입니다. 자세한 설명 감사합니다!