> ## Content Index
> Fetch the complete content index at: https://sanghunkang.com/llms.txt
> Use this file to discover other available public pages before exploring further.

# 고스트 CMS 다국어 블로그: 4. tag 다국어 처리
- URL: https://sanghunkang.com/ko/multilingual-ghost-cms-4-tag-ko/
- Published: 2024-05-13T00:50:00.000Z
- Updated: 2026-09-26T14:41:20.000Z
- Author: Sanghun Kang
- Tags: Ghost, #ko, #multi

news태그 페이지로 접속해보자.

https://{host}/tag/news/

![](https://cdn.magicpages.co/sang.mymagic.page/2024/05/image.png)

해당 태그 페이지를 조회해보면 한국어 포스트(#ko: ko news1, ko news2), 영어 포스트(#en: en news1, en news2), 언어태그가 지정되지 않은 포스트(Comming Soon)가 전부 보여지고 있다.

routes.yaml을 다시 봐보자

```yaml
routes:

collections:
  /:
    filter: "tag:en"
    permalink: /{slug}/
    template: index-en
  /ko/:
    filter: "tag:ko"
    permalink: /ko/{slug}/
    template: index-ko

taxonomies:
  tag: /tag/{slug}/
  author: /author/{slug}/

```

routes.yaml

영어와 한국어 포스트​​​ 경로를 아예 다르게 설정했다. (/, /ko/)

그러나 tag는 그렇게 할 수 없다. tag는 여러개의 경로를 설정할 수 없으며 현재 /tag/{slug}/ 로 설정되어 있다. 즉, 하나의 화면에서 다국어 처리를 해야한다.

다음과 같이 tag페이지를 구현해서 다국어 처리를 해보자.

- Language selector에 선택된 언어태그를 가지는 포스트만 노출시키기
- Language selector에서 언어를 변경하면 보여지는 포스트 변경하기

[0.0.4 · sanghunka/ghost-multilingual-theme@d603058Multilingual tag page![](https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg)GitHubsanghunka![](https://opengraph.githubassets.com/3c958029f322eadb47c93a876c5b2c17609d575f45bfac1552191ac51fd4f8c9/sanghunka/ghost-multilingual-theme/commit/d6030585a2b1a0ece111f6dbb7b434a147ba4005)](https://github.com/sanghunka/ghost-multilingual-theme/commit/d6030585a2b1a0ece111f6dbb7b434a147ba4005?ref=sanghunkang.com)

# Language selector 작동 방식 변경

현재는 Language selector값을 변경시 / 또는 /ko/로 리다이렉트 된다.

tag페이지에서는 Language selector값을 변경시, **리다이렉트 되지 않고** 해당 언어태그를 가지는 포스트만 노출되도록 하고 바꾸어 보겠다.

Language selector가 tag페이지와 tag가 아닌 다른페이지의 경우에 따라 다르게 작동하도록 default.hbs를 수정하자.

```handlebars
{{ghost_foot}}

<script>
    function initializeLanguageSelector() {
        var selector = document.getElementById('languageSelector');
        var currentUrl = window.location.href;
        
        if (!currentUrl.includes('/tag/')) {
            var urlLanguage = currentUrl.includes('/ko/') ? 'ko' : 'en';
            localStorage.setItem('selectedLanguage', urlLanguage);
            selector.value = urlLanguage;
        } else {
            selector.value = localStorage.getItem('selectedLanguage') || 'en';
        }

        selector.style.display = 'block';

        selector.addEventListener('change', function() {
            localStorage.setItem('selectedLanguage', this.value);
            if (!currentUrl.includes('/tag/')) {
                window.location.href = this.value === 'ko' ? '/ko/' : '/';
            }
            else {
                window.location = window.location.href;
            }
        });
    }
    
    initializeLanguageSelector();
</script>
```

- 8행과 20행에서 tag페이지인지 아닌지 조건을 확인한다.
  - if (!currentUrl.includes('/tag/'))
- 13행
  - 만약 tag페이지라면 url을 확인하지 않고 현재 localStorage에 저장된 selectedLanguage값을 그대로 가져와 Language selector의 값으로 설정해준다. 만약 해당 값이 없다면(바로 url로 접속한 경우) 기본값인 en으로 설정해준다.
  - selector.value = localStorage.getItem('selectedLanguage') || 'en';
- 24행
  - 만약 tag페이지라면, /ko/나 /로 리다이렉트하지 않고 그냥 새로고침을 한다.
  - window.location = window.location.href;

새로고침을 하는 이유는 해당 언어에 맞는 포스트를 보여주기 위해서이다. 여기까지 적용을 하면 tag페이지에서 Language selector값을 변경한다고 해서 /ko나 /로 리다이렉트 되진 않는다. 그러나 해당 언어에 맞는 포스트가 보이진 않는다. 이를 위해서 tag.hbs를 수정해야 한다.

# tag.hbs 수정

수정된 tag.hbs 코드는 아래 링크에서 확인할 수 있다.

[ghost-multilingual-theme/multi/tag.hbs at d6030585a2b1a0ece111f6dbb7b434a147ba4005 · sanghunka/ghost-multilingual-themeContribute to sanghunka/ghost-multilingual-theme development by creating an account on GitHub.![](https://github.githubassets.com/assets/pinned-octocat-093da3e6fa40.svg)GitHubsanghunka![](https://opengraph.githubassets.com/c27e8f30296bd605509d2e0135896bce8770d799110276aea7184c2befac4611/sanghunka/ghost-multilingual-theme)](https://github.com/sanghunka/ghost-multilingual-theme/blob/d6030585a2b1a0ece111f6dbb7b434a147ba4005/multi/tag.hbs?ref=sanghunkang.com)

아이디어는 다음과 같다.

- 템플릿은 서버사이드에서 처리된다. 프론트엔드에서 가지고 있는 localStorage값을 활용해 특정 언어의 포스트만 가져올 수 없다.
- 일단 다 가져온 다음에 거르는 방식을 활용해야 한다.
- tag페이지에서 post는 <div class="post-card"> 형태이다. 이 div에 언어정보도 함께 넣어준 뒤 프론트엔드에서 필터링을 하자.

그러나 문제는 해당 포스트가 어떤 언어태그를 가지고 있는지 템플릿단에서 알 수 있는 방법이 없다. 이를 해결하기위해 첫번째 포스트에서 정한 이 튜토리얼의 규칙이 있다.

💡

두번째 태그를 언어태그의 위치로 정하자

```handlebars
{{#foreach posts}}
    <div class="post-card" data-language="{{tags.[1].name}}">
        {{!-- The tag below includes the markup for each post - partials/post-card.hbs --}}
        {{> "post-card"}}
    </div>
{{/foreach}}
```

두번째 태그(tags.\[1\].name)를 가져오면 해당 포스트의 언어를 템플릿단에서 넘겨줄 수 있게 된다.

이제 프론트엔드 부분을 보자. 먼저 모든 post-card를 안보이게 처리해야 한다. opacity를 0으로 만들자. language selector에서 언어 변경시 포스트가 부드럽게 나나는 효과를 주기 위해 5번행을 추가했다.

```handlebars
<style>
    .post-card-excerpt,
    div.post-card {
        opacity: 0; /* Initially set all post cards to be transparent */
        transition: opacity 0.5s ease; /* Transition for smooth display */
    }
</style>
```

조건에 맞는 포스트는 opacity를 1로 만들어서 보이게 하자

```handlebars
<script>
document.addEventListener('DOMContentLoaded', function() {
    const selectedLanguage = localStorage.getItem('selectedLanguage') || 'en';  // Read language setting from local storage or use default 'en'
    const postCards = document.querySelectorAll('div.post-card[data-language]');
    let visibleCount = 0;
    postCards.forEach(card => {
        // Remove '#' character and update language setting
        const language = card.getAttribute('data-language');
        const cleanedLanguage = language.replace('#', '');
        card.setAttribute('data-language', cleanedLanguage);
        // Check if it matches the selected language, then show or hide
        if (cleanedLanguage !== selectedLanguage) {
            card.style.display = 'none';
        } else {
            visibleCount++;  // Count the number of posts that match the selected language
            setTimeout(() => {  // Use setTimeout for a smooth display
                card.style.opacity = 1;  // Set opacity to 1 to make the element visible
            }, 10);
        }
    });
    // Dynamically update text
    const collectionText = document.querySelector('.post-card-excerpt');
    if (collectionText) {
        const text = visibleCount === 0 ? 'zero posts' :
                    visibleCount === 1 ? '1 post' :
                    `${visibleCount} posts`;  // Set text based on the count
        collectionText.innerHTML = `A collection of ${text}`;  // Set text in HTML
        setTimeout(() => {  // Use setTimeout for a smooth display
            collectionText.style.opacity = 1;  // Set opacity to 1 to make the element visible
        }, 10);
    }
});
</script>
```

- localStorage에 저장된 selectedLanguage값을 가져오며 해당 값이 없는 경우 기본깂인 'en'을 쓴다.
- 언어태그는 #en 또는 #ko이다. selectedLangugae값은 en또는 ko이다. 직접적인 비교를 위해 data-language attribute에서 #을 전부 제외해주자.
- 조건에 맞지 않으면 display = 'none', 조건에 맞으면 opacity = 1로 변경해서 포스트를 노출시킨다
- 이 과정을 처리하며 visibleCount값을 카운트해서 몇 개의 포스트가 있는지 화면에 나타내준다.

# 결과

![](https://cdn.magicpages.co/sang.mymagic.page/2024/05/image-3.png)

원하는대로 잘 구현되었다. 더 간결한 방법으로 CSS처리를 할 수 있을거 같은데 내 지식으로는 여기까지가 최선인듯 하다.

# 앞으로

- About, Author페이지 다국어처리
- 좌측상단 로고 클릭시 무조건 /로 리다이렉트 됨

아직 처리할 부분이 많이 있다. 그러나 사용성에 크게 영향을 미치지 않는 부분이라 차근차근 수정해보려고 한다.

[고스트 CMS 다국어 블로그: 5\. 홈 링크 다국어 처리네비게이션바, 푸터, 에러페이지에서 홈링크를 각 언어에 맞는 다국어로 연결하는 방법을 설명한다. 네비게이션바, 푸터, 에러페이지에 home링크가 존재한다. 이 링크는 @site.url로 설정되어있으며 다국어 설정과 상관없이 default 언어의 메인페이지로만 연결되어있다. 이 링크를 현재 활성화된 언어에 맞게 연결되도록 수정해보자. <a class=“gh-head-logo{{#unless @site.logo}} no-image{{/unless}}” href=”{{#if (block “lang”)}}{{@site.url}}/{{block “lang”}}{{else}}{{@site.url}}{{/if}}”> default.hbs에서 기존에 사용하던 방식처럼 block “lang”을 if문 조건으로 활용해서 처리하면 정상적으로 작동한다.</a>![](https://sanghunkang.com/content/images/icon/favicon-1.ico)Sanghun's BlogSanghun Kang![](https://sanghunkang.com/content/images/thumbnail/ghost-1.png)](https://sanghunkang.com/ko/multilingual-ghost-cms-5-handling-multilingual-home-link-ko/)