(구조화된) 태그의 더 나은 내비게이션

여러분 안녕하세요,

태그가 네비게이션에서 더 구조화된 가시성을 갖도록 하려고 노력하고 있습니다. 특히 부모 > 자식 구조에 의존하는 우리에게는 더 그렇습니다. 우리는 태그가 40개 조금 넘게 있으므로, 태그를 위한 구조화된 네비게이션(이 자리를 빌려 말씀드리면, 많은 포럼에서 태그가 극도로 과소 활용되고 있으며, Discourse는 이 부분에서 탁월합니다!)은 꽤나 중요합니다.

Discourse의 네이티브 네비게이션 위에 여러 개의 메뉴를 추가하는 것은 어리석은 일이므로, 제 제안(이라고 생각하는데)은 크게 부담스러운 것이 아닙니다. 아이디어로 이것을 어설프게 목업해 보았어요 …

이런 기능이 이미 존재한다면 제가 찾지 못한 것 같습니다. @Johani님의 컴포넌트가 가장 근접하지만, 불행히도 구조화되어 있지 않습니다.

어쨌든, 피드백을 정말로 듣고 싶습니다. "이건 말이 안 돼"나 “GitHub에서 이거 찾는 데 10초밖에 안 걸렸는데, 너는 신참이구나” 같은 반응도 좋습니다.

감사합니다!

2개의 좋아요

일부 사이트에는 parent > child 태그가 너무 많아 모두 표시할 수 없습니다.

예를 들어, 메타의 태그를 확인해 보세요.

https://meta.discourse.org/tags

2개의 좋아요

그 의견에 동의합니다. [tip-toeing] 메타의 예시는 태그를 사용하는 최선의 방식이 아니라고 생각합니다. 태그에 대한 명확한 모범 사례가 있는 것도 아니지만, 태그에 대해 통제된 어휘를 가지고 있으며 카테고리보다 태그에 훨씬 더 크게 의존하는 우리 같은 사람들에게 단순히 하나의 옵션으로라도 유용할 수 있습니다. 제 예시는 단순히 그 정도였을 뿐이죠… 다른 분들이 더 좋은 아이디어를 가지고 있을 것 같습니다!

2개의 좋아요

태그 페이지를 그대로 사용하지 않는 이유는 무엇일까요? 해당 페이지 링크를 다양한 방식으로 강조할 수 있습니다. 페이지 자체는 기본적으로 그룹별로 구조화하는 것을 지원합니다.

그 후 태그에 대해 사용자 지정 스타일을 추가할 수 있습니다:

또는 전체 페이지 레이아웃의 스타일을 지정하여 더 구체적인 프레젠테이션을 만들 수도 있습니다.

2개의 좋아요

네, 태그 페이지와 태그 페이지의 유연성을 정말 좋아합니다. 정말 좋습니다. 하지만 태그 페이지는 어디에나 있는 것은 아닌 반면, 메뉴는 카테고리에서처럼 동적이고 항상 존재하는 내비게이션을 제공하게 됩니다.

저와 같이 카테고리보다 태그에 훨씬 더 많이 의존하는 사람들이 있을 것이라고 추측합니다. 이는 직관에 반하는 것처럼 보일 수 있지만, 특정 맥락에서는 합리적입니다. Tags 게시물에서 사용된 자동차 예시조차도 이와 같은 기능에서 이점을 얻을 수 있습니다. 예를 들어 자동차 애호가들을 위한 경우라면, 카테고리보다는 태그(Ford vs Ferrari) 사이를 오가는 것을 선호할 수 있습니다.

다시 말하지만, 아직 이 기능을 준비하지 못했을 수도 있습니다. 하지만 여러분의 아이들은 이 기능을 좋아할 것입니다. :wink:

1개의 좋아요

더 동적인 해결책을 찾으신다면 정말 기쁠 것 같아요! 하지만 수동으로 유지 관리할 필요가 없는 것을 원하신다면 상당한 양의 코딩이 필요할 것 같습니다. 그 전까지는 태그 페이지 링크를 더 눈에 잘 띄게 배치하는 것으로 충분할 것 같아요 :slight_smile:

Screenshot from 2021-10-22 21-57-26

제 경험상 태그를 훨씬 더 사용자 친화적으로 만드는 또 다른 측면은 적절한 태그 배너입니다. 태그에 설명을 추가할 수 있도록 tag-banners 컴포넌트에 추가하는 간단한 컴포넌트를 만들었습니다: https://github.com/nolosb/discourse-tag-banners-descriptions

3개의 좋아요

조금 다른 방향: 주제와 주제 목록에서 태그 렌더링을 계층 구조의 브레드크럼 스타일로 표시하도록 변경했습니다: “부모 > 자식” 대신 “자식, 부모” 형태가 아닌 것입니다.

제 해결책은 다소 사이트 특화적이고 해킹적인 부분이 있었지만, 최종 결과는 만족스럽습니다.

제가 한 일과 여러분이 하려는 일을 가로막는 가장 큰 장애물은 discourse가 태그 그룹을 사전 로드하지 않아서 API 요청을 하지 않으면 필요할 때 사용할 수 없다는 점입니다. 카테고리 구조가 사전 로드되는 것과 같은 방식으로 태그 그룹도 사전 로드되어야 한다고 생각합니다.

3개의 좋아요

여기서의 문제는 기술적 한계가 아니라 공간의 한계입니다.

여기서 언급된 바와 같이

사용자로서 당신의 경험을 상상해 보세요. 웹사이트에서 메뉴를 열었을 때 이 모습이 보입니다.

최소한 압도당할 것입니다. 특히 결과물을 좁혀 보일 수 있는 검색 기능이 없는 그 메뉴에서는 더욱 그렇습니다.

따라서 여러분이 하려는 것과 사용자가 경험하기를 원하는 것 사이의 균형점을 찾아보겠습니다. 어떻게 해야 할까요? 제한된 수의 태그 그룹을 표시하고 더 볼 수 있는 것이 있음을 나타내면 됩니다. 즉, 다음과 같은 형태입니다:

그렇다면 어떻게 해야 할까요?

다음은 그 코드입니다:

<script type="text/discourse-plugin" version="0.8">
const MAX_TAGS_TO_SHOW = 20;
const Category = require("discourse/models/category").default;
const siteSettings = api.container.lookup("site-settings:main");
const tagStyle = siteSettings.tag_style;

const getNumberOfTags = (tags, categoryTagsGroups) => {
  let count = 0;
  count = tags.length;
  for (const categoryTagsGroup of categoryTagsGroups) {
    count = count + categoryTagsGroup.tags.length;
  }
  return count;
};

fetch("/tags.json")
  .then(response => response.json())
  .then(data => {
    try {
      const tags = data.tags;
      const hasCategoryTagGroups = data.extras?.categories;

      if (hasCategoryTagGroups) {
        const categoryTagsGroups = data.extras.categories;
        let moreCount = getNumberOfTags(tags, categoryTagsGroups);
        let visibleCount = 0;

        const content = [];
        for (const categoryTagsGroup of categoryTagsGroups) {
          const category = Category.findById(categoryTagsGroup.id);
          const name = category.name;
          const childTags = categoryTagsGroup.tags;
          const childTagNodes = [];

          childTags.forEach((tag, index) => {
            if (visibleCount <= MAX_TAGS_TO_SHOW) {
              childTagNodes.push(
                api.h(
                  "li.tag-link-item",
                  api.h(
                    `a.discourse-tag.tag-link.${tagStyle}`,
                    { href: `/tag/${tag.text}` },
                    tag.text
                  )
                )
              );
              moreCount--;
              visibleCount++;
            }
          });

          if (childTagNodes.length) {
            content.push([
              api.h("li.heading", api.h("span", name)),
              childTagNodes
            ]);
          }
        }

        api.decorateWidget("menu-links:after", helper => {
          if (helper.attrs.name !== "general-links") return;
          return api.h("div.clearfix", [
            api.h("ul.tag-links", [
              api.h("a.categories-link", { href: "/tags" }, [
                "태그 ",
                moreCount ? `(${moreCount}개 더 보기)...` : ""
              ]),
              content
            ]),
            api.h("hr")
          ]);
        });
      }
    } catch (error) {
      console.error("햄버거 태그 테마 구성 요소에 문제가 있습니다");
      console.error(error);
    }
  })
  .catch(console.error);

</script>

이 코드는 테마의 header 탭에 넣으면 됩니다. 상단의

const MAX_TAGS_TO_SHOW = 20;

을 표시하고 싶은 태그 수로 변경할 수 있습니다.

그 다음 링크 스타일을 지정하기 위해 CSS를 조금만 추가하면 됩니다. 시작할 수 있도록 기본적인 것을 하나 소개합니다.

.tag-links {
  .heading {
    padding: 0.25em 0.5em;
  }
  .tag-link-item {
    background-color: transparent;
    display: inline-flex;
    align-items: center;
    padding: 0.25em 0.5em;
    width: 50%;
    box-sizing: border-box;
    .tag-link {
      display: inline-flex;
      width: 100%;
      &:hover {
        color: var(--primary);
      }
    }
  }
}

위 자바스크립트 코드는 사이트 설정에서 설정된 태그 스타일을 따름에 유의하세요. 또한, 사이트가 태그에 매우 많이 의존한다면 해당 메뉴에 카테고리를 표시할 필요가 없을 수 있습니다. 이를 숨기면 사용자 혼란을 줄이는 데 도움이 됩니다.

또한, 확장된 태그 섹션을 추가한다면 이 링크는 중복이 됩니다.

따라서 다음과 같은 것으로 이를 숨겨 보겠습니다.

.panel-body {
  .category-links,
  .categories-separator,
  .widget-link[href="/tags"] {
    display: none;
  }
}

마지막으로, 여기에서 언급된 바와 같이:

이 데이터는 기본적으로 /tags를 방문하지 않는 한 클라이언트로 전달되지 않으므로, 위의 코드는 홈페이지에서 추가 요청을 수행합니다(방문당 1회만 실행). Discourse는 모든 것을 매우 단순하게 유지하려 하므로, 데이터가 필수적이지 않은 경우 기본적으로 로드하지 않습니다.

이것이 Discourse 코어에 가까운 시일 내에 추가될 것으로 보이지는 않습니다. 따라서 서버에서 실행되는 플러그인을 작성하고 싶지 않는 한, 추가 요청을 하는 것이 거의 유일한 선택지입니다.

7개의 좋아요

조, 정말 감사합니다! 훌륭해요!

간단한 질문이 몇 가지 있습니다… 원래 답변에서는 자식 태그 대신 태그 그룹을 기반으로 가져오시는 걸 봤습니다. 특별한 이유가 있을까요? 자식 태그를 표시하지 못했지만, 태그 그룹을 사용한 초기 답변 방식은 잘 작동했습니다.

유일한 문제는 로그아웃된 사용자에게 태그가 표시되지 않는다는 점입니다. API 관련 문제라고 추정하는데, 이를 우회할 수 있는 방법이 있을까요?

그 외에는 정말 감사할 따름입니다—다른 사람들도 이 코드를 유용하게 사용할 수 있을 거라고 확신합니다. 정말 감사합니다!

2개의 좋아요

이 작업을 좀 더 쉽게 만들어 줄 테마 컴포넌트를 만들었습니다. 아래 중 하나를 선택할 수 있습니다.

  1. 중첩 태그 그룹
  2. 중첩 허용 카테고리 태그
  3. 평탄한 최상위 태그

자세한 내용은 여기서 확인하세요.

1개의 좋아요

Joe를 Discourse의 수호성으로 추천합니다.

1개의 좋아요

하하하, 나도 트레이닝 코스를 위해 하나 만들고 있었어.

아쉽네.

그래도 고마워

2개의 좋아요