ArticleListItem.svelte

손대중·2022년 7월 14일
0

ArticleListItem.svelte 에 필요한 데이터는 아래와 같다.

두가지 문제가 있는데, 하나는 API 서버에서 주는 Article 데이터에는 "대표 이미지" 데이터가 없는 것, 두번째는 contents 데이터는 html 텍스트라는 것이다.

데이터 자체를 추가할 수도 있지만... 뭐 List length 가 막 100개 1000개 될것 같지는 않아서... 서버를 수정하기 보다는 프론트에서 파싱하기로 결정했다.

나중에 문제가 되면 그때 가서 다시 생각해보면 될듯... 뭐 일단 파싱하는 로직은 아래와 같다.

  • contents 파싱
    • 첫번째 <img /> 의 src 정보를 가져와 대표 이미지로 설정
    • <p>, <li> 태그 안에 있는 text 만 뽑아내서 contents 로 설정
      • <img>, <h1~5>, <div>, <blockquote>, <table>, <code> 은 그냥 빈스트링으로 replace
      • <br>, <li> 는 스페이스 하나 - ' ' 로 replace
      • 나머지 태그들 - <~> 전부 빈스트링으로 replace

정규식을 사용해 contents 데이터를 파싱하는 코드를 짰다.

정규식은 구글과 여러 능력자분들의 코드 & 블로그를 참조해서 만들었다.

ArticleListItem.svelte 의 전체 코드는 아래와 같다.

참고로 default 이미지는 내가 침착맨님을 좋아하기 때문에 twitch 의 침착맨 채널의 대표 아이콘 이미지를 따왔음. (임시 이미지)

임시로 정한 default 이미지이고, 원래 default 이미지는 프론트에 포함되어 있어야 함.

  • ArticleListItem.svelte

    <div class="article-list-item-cell-container">
        <div class="article-list-item-cell-image-box">
            <img alt="..." src={image} on:error={() => {image = defaultImage}}/>
        </div>
    
        <div class="article-list-item-cell-text-box">
            <div>
                <h3 style="color: greenyellow;">{title}</h3>
                <p>{contents}{@html '...'}</p>
                <span>{created}</span>
            </div>
        </div>
    </div>
    
    <script>
        export let article;
    
        let defaultImage = 'https://static-cdn.jtvnw.net/jtv_user_pictures/dde955e8-5fae-44dc-98db-79b3b14afea2-profile_image-70x70.png';
        let image = defaultImage;
        let title = article?.title || 'Title...';
        let contents = 'Contents....';
        let created = '2022년 7월 7일';
    
        // article.contents 내에서 첫번째 이미지 src 추출해서 image 로 설정
        const reg = new RegExp(/(<img[^>]+src\s*=\s*[\"']?([^>\"']+)[\"']?[^>]*>)/, 'i');
        image = reg.exec(article.contents)[2] || defaultImage;
    
        // <img>, <h1~5>, <div>, <blockquote>, <table>, <code> 은 그냥 빈스트링으로 replace
        // <br>, <li> 는 ' ' 로 replace
        // 나머지 태그들 - <~> 전부 빈스트링으로 replace
        contents = article.contents
            .replace(/(<img[^>]*>)|(<h1[^>]*>.*<\/h1>)|(<h2[^>]*>.*<\/h2>)|(<h3[^>]*>.*<\/h3>)|(<h4[^>]*>.*<\/h4>)|(<h5[^>]*>.*<\/h5>)|(<h6[^>]*>.*<\/h6>)|(<div[^>]*>(?!<div).+?<\/div>)|(<blockquote[^>]*>(?!<blockquote).+?<\/blockquote>)|(<table[^>]*>(?!<table).+?<\/table>)|(<code[^>]*>(?!<code).+?<\/code>)/gi, '')
            .replace(/(<br[^>]*>)|(<li[^>]*>)/gi, ' ')
            .replace(/<[^>]*>?/gi, '');
    </script>
    ...

이제 Article 데이터를 가져와서 Article List 를 노출하는 로직을 적용하자.

그 전에... test 데이터 정리 좀 하고

0개의 댓글