Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[글] 같은 카테고리 글 목록 추가 방안 #18

Closed
binchoo opened this issue May 21, 2021 · 7 comments
Closed

[글] 같은 카테고리 글 목록 추가 방안 #18

binchoo opened this issue May 21, 2021 · 7 comments
Assignees
Labels
리팩터 New feature or request
Milestone

Comments

@binchoo
Copy link
Owner

binchoo commented May 21, 2021

연관: #8

[개선사항]
보통 블로그 글 하단엔 같은 카테고리 내 글 목록들이 전시되곤 한다.
하지만 티스토리가 기본제공하는 카테고리 글 목록 위젯은 너무 레가시하다.

해당 위젯이 어떤 패킷을 주고 받는지 분석하고, plore 테마에 맞게 뷰를 제공하도록 하자.
유저가 이탈하지 않으려면 끊임없는 글 소비를 유도해야 한다. 이 이슈는 그런 측면에서 치명적 이슈이므로 반드시 해결 바란다.

@binchoo binchoo added the 리팩터 New feature or request label May 21, 2021
@binchoo binchoo added this to the 1.0.2 milestone May 21, 2021
@binchoo binchoo self-assigned this May 21, 2021
@binchoo
Copy link
Owner Author

binchoo commented May 21, 2021

[해결 방안]

  1. div.another_category 내 요소들에게 CSS 스타일 지정해 주는 방식.
  2. div.another_catergory의 정보를 토대로 새로운 뷰를 렌더링 하는 방식.
    image

[1안에 대하여]
CSS로 div.another_category 내부 요소의 테마를 작성하면 될 일이다.

[2안에 대하여]
카테고리 글 목록의 구조를 새로 짠다고 해도 기본 제공되는 테이블 구조랑 달라질 가능성은 적다.
그러므로 기본 구조는 유지하되 헤더, 테이블 열, 버튼 등의 뷰 확장을 제공하는 형태가 나을 것이다.

[시나리오]

  • 블로그 테마에 맞추어 카테고리 글 목록을 씨밍하는 건 필수이다. 그러므로 1안은 필수 작업이다.
  • 유저는 카테고리 글 목록의 테이블 구조를 확장할 수 있다.
    • 헤더 영역을 설정할 수 있다. 기본적으로 헤더는 미노출이다.
      • 헤더 생성 시, 내부에 행 2개가 추가된다.
      • 첫째 행의 길이는 모든 열을 커버한다.
      • 둘째 행은 제각각 길이를 갖는 열로 쪼개질 수 있다. 각 열의 길이합은 모든 열의 길이와 동일해야 한다.
      • 헤더 둘째 행의 열 갯수에 맞추어, 바디의 열 갯수도 변경된다.
    • 상단 뷰, 하단 뷰를 추가할 수 있다.
    • 뷰의 배치는 Renderer 스니펫을 주입하여 렌더링 해야 한다.

[티스토리 기본 제공 구조]

<div class="another_category another_category_color_gray">
    <h4 id="'컴퓨터공학&nbsp;>&nbsp;안드로이드 프로그래밍' 카테고리의 다른 글(300)" class="">'<a
            href="/category/컴퓨터공학">컴퓨터공학</a>&nbsp;&gt;&nbsp;<a href="/category/컴퓨터공학/안드로이드%20프로그래밍">안드로이드 프로그래밍</a>'
        카테고리의 다른 글</h4>
    <table>
        <tbody>
            <tr>
                <th>
                    <a href="/39?category=996542" class="current">[안드로이드][TabLayout] 탭의 클릭, 활성, 눌림 상태마다 배경
                        바꾸기</a>&nbsp;&nbsp;<span>(0)</span>
                </th>
                <td>
                    2021.05.11</td>
            </tr>
            <tr>
                <th>
                    <a href="/38?category=996542">[안드로이드][Volley] 쿠키가 있는 HTTP 요청 작성하기</a>&nbsp;&nbsp;<span>(0)</span>
                </th>
                <td>
                    2021.05.07</td>
            </tr>
        </tbody>
    </table>
</div>
  • 활용할 필수 요소
    • 카테고리명: div.another_category>h4>a로 취득하는 모든 요소
    • 글 목록: div.another_category th a로 취득하는 모든 요소
    • 글 작성일: div.another_category td로 취득하는 모든 요소

@binchoo
Copy link
Owner Author

binchoo commented May 22, 2021

[인터페이스 정의 (슈도)]

  • 클라이언트 슈도 코드
var decorator = new CategoryPostDecorator('div.another_category');
decorator.firstHeader(width=1, (posts)=>{}};
decorator.secondHeader([widths=1, 1, 1], (posts, i)=>{});
decorator.body((posts, i, j)=>{});
decorator.topView((posts)=>{});
decorator.bottomView((posts)=>{});
  • 렌더러 스니펫 예제
var decorator = new CategoryPostDecorator();

decorator.firstHeader(2, (posts)=> {
  const categoryString = posts['category'];
  const num = posts['data'].length;
  const h3 = document.createElement("h3");
  h3.textContent = `${categoryString} 관련글 ${num}개`;
  return h3;
});

decorator.secondHeader([1, 1], (posts,  i)=> {
  const titles = ["제목", "작성일"];
  const h3 = document.createElement("h3");
  h3.textContent = titles[i];
  return h3;
});

decorator.body((posts, i, j)=> {
  const post = posts.data[i];
  if (j == 0) {
    const a = document.createElement('a');
    a.href = post.link;
    a.textContent = post.title;
    return a; 
  }
  if (j == 1) {
    const h5 = document.createElement('h5');
    h5.textContent = post.date;
    return h5;
  }
});

decorator.topView((posts)=> {
  const div = document.createElement('div');
  const prev = document.createElement('button');
  const next = document.createElement('button');
  const currentIndex = posts.currentIndex;
  
  prev.textContent = '최신 글';
  if (currentIndex == 0) {
    prev.disabled = true;
  } else {
    prev.onclick = ()=>{ location.href = posts.data[currentIndex - 1].link; }
  }

  next.textContent = '이전 글';
  if (currentIndex == posts.data.length - 1) {
    next.disabled = true;
  } else {
    next.onclick = ()=>{ location.href = posts.data[currentIndex + 1].link; }
  }

  div.appendChild(prev);
  div.appendChild(next);
  return div;
});
  • posts 객체
{
  category: String, 
  category_links: Array<String>,
  data: Array<Post>,
  currentIndex: Int
}
  • post 객체
{
  title: String,
  link: String,
  date: String
} 

@binchoo
Copy link
Owner Author

binchoo commented May 23, 2021

[테스트로 AnocatDecorator가 생성한 뷰 형태]

<div class="another_category another_category_color_gray">
    <div class="top-view">
        <div><button disabled="">최신 글</button><button>이전 글</button></div>
    </div>

    <table>
        <thead>
            <tr class="first-header">
                <th colspan="2">
                    <h3>컴퓨터공학 &gt; 개인 프로젝트 관련글 2개</h3>
                </th>
            </tr>
            <tr class="second-header">
                <th colspan="1">
                    <h3>제목</h3>
                </th>
                <th colspan="1">
                    <h3>작성일</h3>
                </th>
            </tr>
        </thead>
        <tbody class="table-body">

            <tr>
                <th><a href="https://binchoo.tistory.com/41?category=998658">[Github] 깃허브 매일 커밋 잔디밭 제조기 (Grass
                        Hoppers)</a></th>
                <th>
                    <h5>
                        2021.05.16</h5>
                </th>
            </tr>
            <tr>
                <th><a href="https://binchoo.tistory.com/40?category=998658">[티스토리 스킨] 개발자와 잘 어울리는 티스토리 스킨: Plore</a>
                </th>
                <th>
                    <h5>
                        2021.05.15</h5>
                </th>
            </tr>
        </tbody>
    </table>
</div>

image

@binchoo
Copy link
Owner Author

binchoo commented May 23, 2021

[CSS 셀렉터 정의]

  1. 전역 지정 .another_category
  2. 헤더 지정 .first-header, .second-header
  3. 바디 지정 .table-body
  4. 확장 뷰 지정 .top-view, .bottom-view

[파일명 변경]
Rename tistory-category-posts-decorator.js to anocat.js

@binchoo
Copy link
Owner Author

binchoo commented May 25, 2021

[레이아웃 개념 추가]
Anocat은 테이블 구조를 지니고 있는데, 사용자는 자유롭게 이 틀 안에서 뷰를 꾸밀 수 있다.
테이블 구조를 어떻게 작성하느냐가 관건인데, 미리 유용한 템플릿을 제공하면 좋을 것 같다.

  1. 수평 카드 레이아웃
    first-header 길이 5, second-header 길이 1짜리 5개. 결국 body는 1행, posts.length열 배치를 갖는다.
  2. 수직 카드 레이아웃
    first-header 길이 1, second-header 길이 1. 결국 body는 posts.length행 1열 배치를 갖는다.
var decorator = AnocatDecorator.useLayout('card-vertical');
// var decorator = AnocatDecorator.useLayout('default');
// var decorator = AnocatDecorator.useLayout('card-horizontal');

decorator.firstHeader(...) 
// error; 'card-vertical' 레이아웃을 사용한다고 했으므로 사용자 주입할 수 없도록 막는다.
decorator.secondHeader(...) 
// error; 
decorator.tableBody(...) 
// good!
decorator.bottomView(...)
// good!

@binchoo
Copy link
Owner Author

binchoo commented May 25, 2021

[클라이언트 시나리오 고찰]

  1. 처음부터 다 설정하기
var decorator = AnocatDecorator();
decorator.topView(...)
  .firstHeader(...)
  .secondHeader(...)
  .tableBody(...)
  .bottomView(...)
  .commit();
  1. 프록시 클래스에 모든 절차 정의하여 사용하기
var decorator = MyAnocatDecorator();

class MyAnocatDecorator {
  constructor() {
    this.realDecorator = AnocatDecorator().topView(...)
      .firstHeader(...)
      .secondHeader(...)
      .tableBody(...)
      .bottomView(...)
      .commit();
  }
  get() = { return this.realDecorator; }
}
  1. 스태틱 팩토리 패턴으로 레이아웃 가져와서 커스터마이징 하기
    이 때, 레이아웃을 '가져온다'는 개념은 어떤 코드로 구현하게 될까?
    파일 어딘가 미리 정의된 'card-vertical' 전용 'viewConfig' 객체를 가져다 쓰는 형태일 것.
    이 파일은 외부 파일이어야 하는 게 좋은 디자인.
var decorator = AnocatDecorator.useLayout('card-vertical');
decorator.tableBody(...).commit();

배포에 용이하며, 클라이언트 코드가 깔끔하고, 적당히 의존성 주입이 가능한 것은?
당연히 3번 강추. 이 시나리오로 사용자를 유도하자. useLayout 개념은 충분히 Affordance가 있다.

@binchoo
Copy link
Owner Author

binchoo commented May 26, 2021

useLayout까지 구현 완료하였다.
이후 CSS 테마 작성 작업부터 binchoo/anocat#2 로 이관한다.

@binchoo binchoo closed this as completed May 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
리팩터 New feature or request
Projects
None yet
Development

No branches or pull requests

1 participant