Hugo 섹션간 순회 이전 이후
개요
이 휴고 템플릿은, 깊이 우선 탐색, 전위 순회 방식으로 이전/이후 항목을 반환한다.
두 개의 템플릿 함수가 있다.
- 이후(Heavier) 항목: 주어진 항목에서 위 그림의 화살표 방향의 인접 항목을 반환한다.
- 이전(Lighter) 항목: 주어진 항목에서 위 그림의 화살표 반대방향의 인접 항목을 반환한다.
이러면 이전/이후 방향별 각 하나의 함수만으로, 사이트의 모든 항목을 순회할 수 있다.
섹션간 탐색이 필요한 사람들이나, 문서의 구조 변경을 자주 해야 하는 사람들에게 유용할 것이라고 생각한다.
참고사항
- 휴고에서 제공하는 PrevInSection / NextInSection 이 섹션이 아닌 페이지만을 대상으로 하는데 반해, 이 템플릿 함수들의 대상은 페이지와 섹션, 양쪽 모두이다.
- 본 템플릿 함수는 기술 문서의 탐색을 염두에 두고 만들어졌기 때문이다. 대개, 기술 문서 사이트에서 휴고의 섹션에 해당하는 하위 문서 목록 페이지에는, 하위 항목들에 대한 소개나 개요 정보가 배치된다. 나는 이전/이후의 방식으로 사이트를 탐색을 할 때, 이런 정보들이 스킵되지 않기를 바랬다.
- 이 템플릿 함수들은 실제로 깊이 우선 탐색을 행하지는 않는다. 단지 각 항목들이 자신의 이전/이후 항목만 찾아 반환한다.
사용
저장소: https://github.com/hyaniner/hugo_prev_next_traversal_across_sections
- 휴고 프로젝트의 루트 디렉토리에 위의 저장소를 폴더째 붙여넣기 한다.
- 아래와 같이 템플릿 상에서 호출한다.
- 이전 항목(Weight 값이 작은 항목 방향):
1
{{ partial "navigation/traversal_across_sections/lighter.hugo" . }}
- 다음 항목(Weight 값이 큰 항목 방향):
1
{{ partial "navigation/traversal_across_sections/heavier.hugo" . }}
- 이전 항목(Weight 값이 작은 항목 방향):
- 디폴트 경로는
hugo_project_root/layouts/partials/navigation/traversal_across_sections/
로 되어있다. 만약 각 파일들을hugo_project_root/layouts/partials/
에 위치시켜 사용하고 싶다면, 코드에서navigation/traversal_across_sections/
부분을 삭제하고 사용해야 한다.
License: Apache License 2.0.
세부사항들
동기
휴고 에서 제공하는 함수들로도 위와 같은 순회를 할 수 있긴 하다. 하지만 파란색 화살표와 녹색 화살표 부분은 서로 다른 기능을 사용해야 하고, 빨간 화살표 부분은 휴고 에서 기본으로 제공되는 함수가 존재하지 않기 때문에, 사용자가 직접 구현해야 한다. 이 템플릿은 그림에 나온 순회에 필요한 수단들을 방향 별로 통합하는 역할을 한다.
동작 방식
이 템플릿은 아래와 같이 동작한다.
- 이전 항목 (weight 값이 작은 방향)
- 만일 현재 항목이 자신이 속한 섹션에서 첫 항목일 경우, 자신의 상위 항목을 반환한다.
- 만일 현재 항목이 자신이 속한 섹션에서 첫 항목이 아닐 경우, 해당 섹션에서 현재 문서보다 앞의 항목을 찾는다.
- 찾은 항목에 하위 항목이 없다면, 해당 항목을 반환한다.
- 찾은 항목에도 하위 항목이 존재할 경우, 하위 항목이 더 이상 나오지 않을 때 까지 마지막 순서의 항목들을 재귀적으로 탐색을 해서, 하위 항목이 없는 가장 마지막 순서의 항목을 찾아 반환한다.
- 다음 항목 (weight 값이 큰 방향)
- 일단 현재 항목에 하위항목이 존재하면, 첫 하위 항목을 반환한다.
- 만일 현재 항목의 하위항목이 존재하지 않으면,
- 현재 항목이 속한 섹션에서 다음 항목이 존재할 경우, 해당 다음 항목을 반환한다.
- 현재 항목이 속한 섹션에서 다음 항목이 존재하지 않을 경우, 다음 항목을 가진 상위 항목이 나올 때 까지 재귀적으로 상위 항목들을 탐색 한다.
- 만일 다음 항목을 가진 상위 항목이 발견되면, 그 상위 항목의 다음 항목을 반환한다.
- 이 검색 중 홈에 도달하면, 홈을 반환한다.
이 방법이면, 디렉토리 구조 어디에서 호출하든, 일관된 방식으로 이전/이후 항목을 찾을 수 있다.
참고로,
- 현재 문서가 Home 이면 Home 자체를 반환한다.
- Home 의 첫 자손 항목에서 lighter 방향의 항목을 구하거나, 사이트의 폴더 구조상 가장 마지막 문서에서 heavier 방향의 항목을 구하려고 하면, 결과로 Home 이 반환된다.
이름에 관하여
원래 이 녀석의 이름은 “DFS 이전 이후” 였다. 하지만 이렇게 이름을 만든 뒤, 한참 동안 불편했다. 이 템플릿이 깊이 우선 탐색 방향 - 정확히는 전위 순회 방향을 기준으로 이전/다음 항목을 찾기는 한다. 하지만, 구현 자체에는 깊이 우선 탐색이나 전위 순회에 사용되는 전통적인 알고리즘이 포함되어 있지 않다. 해당 알고리즘들에 대한 전형적인 설명들은, 대개, 루트 노드에서 시작해서 전체를 순회하는 것을 목적으로 하고 있다. 하지만, 여기선 오직 각 항목의 입장에서 이전, 이후 항목만 구하면 된다.
사이트 전체의 항목을 순회하면서, 구조를 분석하여 이전/이후 항목에 대한 dictionary collection 을 scratch pad에 만들어놓고 시작하는 코드를 Relearn 테마에서 본 적이 있다. 그 코드를 보고 나도 사이트 전체에 대한 데이터를 만들어놓고 읽어오는 식으로 만들까 생각을 했다. 하지만, 만약 이 처리가 페이지들 별로 병렬적으로 실행된다면, 각 페이지들이 필요한 만큼만 처리를 수행하는 게 더 나을 것이라고 생각했다. 만약, 각 사이트에 “중요한 토픽 섹션” 같은 것들이 존재해서, 페이지 별로 “다음 토픽 섹션 시작 페이지로” “이전 토픽 섹션 시작 페이지로” 같은 링크를 넣을 것이라면, 구조 전체를 먼저 처리하는 방식이 더 나았을 것이다. 하지만 이 사이트에서는 그런 기능이 아직 필요할 것 같지 않았다.
그러면 각 항목들의 입장에서 앞 뒤 항목을 구해오는 방식으로 구현할 경우, 적당한 이름은 뭐가 되어야 할까? 처음에 이 기능에 관해 내가 검색할 때 사용한 단어는 “섹션간 이전 이후"였다.
그래서 지금은 이름을 “섹션간 순회 이전 이후"로 바꿔놨다.
prev/next 대신, lighter/heavier
휴고 의 Prev/Next 에는 슬픈 사연이 있다. (링크) 여러 생각이 드는 부분인데, 하위 호환성은 쉽지 않은 주제라는 걸 이해한다. 이 코드는 weight 에 기반하여 동작한다. 또한, 블로그가 아닌 기술 문서에서 사용하는 것을 전제로 하고 만들었다. 그래서, Previous 와 Next 대신에, lighter 와 heavier 를 사용하는 쪽으로 코드를 수정했다.
기타
비슷한 경우를 접할 다른 사람을 위해 코드를 게시한다.
“사실 그거 휴고의 이 기능을 저렇게 사용하면 더 간단해요"라고 누군가 말해주면 좋을 것 같다.