주어진 임무:
10팀의 아티스트가 만든 10개의 전시물에 대해 국문/영문 소개문, 사진, 아티스트 소개 등을 보여주는 그럴듯한 모바일 브로셔를 만들어라.
실제 돌아가는 결과물: upcyclingtree.dothome.co.kr
전체 소스:
Day 1
- 백엔드가 의외로 고민거리였다. 아무 생각없이 정적 페이지 10*n개를 만들면 머리는 편하겠지만 손이 고생할 거다. 10개의 팀과 10개의 작업물과 각 작업물에 들어가는 n개의 사진을 그렇게 매뉴얼하게 관리하다 보면 분명 어딘가 하나쯤 꼬일 테니까.
- 요컨대 데이터에 최소한의 체계성을 부여해야 한다. 그렇다고 DB 스키마 짜고 CI 같은 본격적인 프레임워크를 깔고 싶지도 않다. 너무 일이 된다. phpSlim 같은 간단한 라이브러리는 아직 건드려도 못 봤고... 음 어떡한다?
- 일단 MVC 자체는 매뉴얼하게 가기로 결정하고 array.php를 작성. 내가 알아보고 관리할 수 있는 선에서 가장 원초적인 정적 데이터배열을 만든다. 이걸 include한 다음 get파라미터에 담긴 변수 따라서 원소 출력시키지 뭐. 어차피 모바일로 잠깐 보고 끌 페이지이기 때문에 URL prettify는 안 해도 된다고 판단.
- 프론트엔드가 그 다음 골칫거리였다. 아무 생각없이 Bootstrap이나 PureCSS를 쓰면 손은 편하겠지만 눈이 고생할 거다. 애초에 모바일 브로셔로서 갖춰야 할 최소한의 미적 감각을 담보할 수가 없을 것이다. 뭐 괜찮은 프론트엔드 프레임워크 없나? 막 뒤져봄.
- 예전에 한번 보고 지나갔던 Framework 7이라는 놈을 다시 찾아냄. 안드로이드/iOS 앱개발자들이 웹개발도 비슷한 느낌으로 해낼 수 있도록 만든 (것으로 생각되는) 소스이다. 지원하는 컴포넌트를 살펴보니 이건뭐 거의 아이폰 네이티브 앱 와꾸가 나오는 게 구상 및 설계상의 문제가 일거에 해결됨. CDN이 있나? 살펴보니 있었다! 오케이 너로 정했다.
- index.php를 짜면서 CSS 클래스와 컴포넌트, js에 익숙해지는 데 하루의 나머지를 다 보냄. 아직은 전체 틀만 잡고 있었으므로 근본 원리는 파악하지 못한 (몰라도 괜찮았던) 단계. 이때는 $data[i][9](index에서 띄울 섬네일 url) 같은 것이 없었다.
- 메뉴 구현은 다음과 같다. navbar에 사이드패널 여는 버튼을 넣고, 그 안에 사이드패널 닫는 버튼을 하나 만들어 넣기. 별문제없이 작동.
- 이미지 호스팅은 비공개 텀블러를 사용하기로 함. 되는 거 확인하고 퇴근.
Day 2
- 출근하자마자 원래 index.php에 통째로 들어 있던 header.php 부분과 footer.php 부분을 분리. 잘 작동하는 것 확인. (개인적으로 뷰를 아예 새로 작성할 때 !doctype html로 시작해서 전체를 다 짜둔 다음 header, footer 등으로 오려내는 습관이 있다. 좋은 습관이 아니다.)
- 최소한의 그리드가 필요하다는 것을 알게 되어 pureCSS의 base.css만 따로 로딩함.
- 사이드패널에 뿌려놓은 메뉴 링크들을 눌렀는데, 404나 에러페이지로 넘어가지 않고 그냥 깜박이고 마는 것이 너무 신기했다. 이개모지? 나중에 쓰겠지만, 프레임워크7의 핵심 작동 원리인 "AJAX 프리로딩" 덕분에 가능한 것이었음.
- framework 7의 기본 CSS는 사이드패널에 리스트로 띄운 메뉴 텍스트를 죄다 자동으로 ellipsis로 줄여버리더라. 작품들의 이름이 좀 길고, 모바일에서 그걸 다 볼 필요가 있기 때문에, 걍 CSS를 뜯어고쳐 다 띄우게 만들어둠.
- 이제 핵심이라고 할 수 있는 detail.php를 작성하기 시작. 원래 구상은 이랬다.
- 적당한 GET파라미터가 지정이 안돼있으면 홈 주소로 리디렉션시킨다. 최소한의 url 에러처리.
- tree 파라미터가 지정돼 있을 경우 "작품소개" 탭을 활성화시켜 작품 소개를 바로 띄운다.
- team 파라미터가 지정돼 있을 경우 "작가소개" 탭을 활성화시켜 작가 소개를 바로 띄운다.
- 작품소개 탭 페이지에서는 "한국어"를 누르면 국문 설명이, "English"를 누르면 영문 설명이 나오게 한다.
- 사진 쪽을 누르면 갤러리를 띄운다. 갤러리에 들어갈 사진들은 array.php에서 하위배열 하나 넣어서 foreach로 뿌리기로.
뭐 더 설명할 것 없이 무쟈게 기초적인(≒무식한) 네비게이션이다. - 작품소개-사진-작가소개는 탭바를 이용하기로 했고, 한국어/English 전환은 탭을 쓰기로 했다. (이름은 비슷한데 영 달라서 되게 헷갈림.) 사진 갤러리는 포토브라우저로 처리.
- 갤러리에 넣을 사진은 곧 받기로 했었으므로 일단 lorempixel을 채워넣음. "Close"를 "닫기"로 고칠 순 없을까? 생각했지만 일단 넘어감. 작가 소개문은 따로 제공받지 않았었으므로 일일이 웹사이트나 SNS를 찾아가서 소개문 및 로고를 찾아 array.php를 보강함. 페이지별로 멀쩡하게 뜨는 것 확인.
- 쫙쫙 잘 뜨길래 야 신난다! 하고 이것저것 눌러보다가… 버그 발견. 사이드메뉴로 detail 뷰에 진입했다가 다른 detail 뷰를 보려고 하면 탭바가 동작을 하지 않는다. 그냥 흰 화면이 뜨고 아무 일도 일어나지 않음. 읭??? 이거 뭐냐??? 모바일 사용자는 눈에 보이는 모든 것을 다 눌러보는 법인지라, 이건 무시할 수 없는 문제상황이라는 판단이 서서 패닉에 걸림.
- 세 시간 동안 스택오버플로를 ㅈ나게 뒤지고 Framework 7 공식 문서를 눈 빠지게 읽음. "해결법"은 못찾음. 설마 싶은 것들은 한두 개 눈에 띄었지만, 이리저리 코드를 고치고 뒤집다 보니 이젠 뭐가 뭔지 모르겠다 싶어서 그만두기로 하고 퇴근. (진짜 뇌도 스택으로 돌아간다면 이런 게 오버플로일까 싶은 걸 경험했다. undo redo를 아무리 눌러봐도 기억이 돌아오질 않았다…)
Day 3
- 출근해서 서브라임 텍스트를 딱 켰는데 생각해 보니 해결된 게 아무것도 없었다. 최악의 경우 이 조치를 단행하면 되겠지… 라고 짐작하고 있던 조치를 단행했다. 모든 링크에 .external 클래스를 부여한 것. 해놓고서 다시 열어보니, 프레임워크7 특유의 스무스한 페이지 움직임(써보면 안다. 진짜 앱 사용하는 것처럼 움직인다)은 없어졌는데 내용 출력 자체는 멀쩡하게 잘 되었다. 허탈.
- 차차 원인을 이해할 수 있었다. 프레임워크7은 기본적으로 모바일앱이 갖는 페이지 개념 아래 개발돼 있어서, 하나의 "페이지(URL 엔드포인트)"가 경우에 따라서 여러 데이터를 가진다는 개념을 이해하지 못함. 그런데 나는 index 아래의 모든 뷰가 detail.php?team=foo 아니면 detail.php?tree=bar 꼴이었던 것이다.
- JS 입장에서는 할 말을 잃고 동작을 중단할 수밖에 없다. 아까 detail 페이지 안에 들어 있는 #tab_tree 하나를 active 걸었는데, (사용자 입장에서는 별개의) detail 페이지 안에 있는 #tab_tree에 active를 또 걸라니 뭔 소리냐 싶겠지.
- 이런 일이 있을까봐, 그리고 Framework 7의 기술적 특성상 준비돼 있던 것이 a태그에 붙일 수있는 .external 클래스였다. 프레임워크7은 페이지를 쫙 읽어본 다음 href 붙은 모든 url을 미리 ajax로 읽어놓는다. 그 다음 스마트하게 동작한다. 예컨대 A라는 링크를 요청했을 때 서버가 404를 외쳤다면, JS는 A를 기억해 놨다가, 사용자가 A를 누를 때 아무 일도 안 일어나게 만든다. 이게 그야말로 모든 링크에 대해 작동할 경우 외부 사이트 DOM까지 읽게 되면 보통 큰일이 아니게 되므로, 구분자를 제공하는 것.
- 이 구분자의 기능은 DOM7 편입을 안 시키는 것. 그러면 ajax 프리로딩 없이 그냥 매번 요청된 URL을 새롭게 요청하게 된다. 당연히 "문제"는 해결된다. 하지만 더 좋은 사용(스무스한 이동 등 진정한 framework 7 사용경험 구현)으로서의 진정한 해결은 안된 상태. (미숙…)
- 그리고 어제의 패닉 리서치 과정에서 한 가지 더 알게 된 사실은, 탭바는 DOM7 전체에서 항상 나오는 메뉴로서 쓰는 것이 best practice라는 것. 생각해 보면 메인화면에 안 나오던 탭바가 세부사항 페이지에서는 나오는 일은 거의 없다. 이것도 아마 스크립트 충돌에 일조한 사항일 것.
- 전날 뒤집어엎으면서 엉망진창 만들어놓은 코드를 재정리. 공식 문서에 따르면 Framework 7의 전형적인 페이지는 다음 구조를 따른다.
body
- panel (상단 전체메뉴. 싫으면 넣지마슈~)
- views (상단을 뺀 나머지 화면 전체 wrapper. 전체DOM에서 유일)
-- view .view-main (기본화면, 전체DOM에서 유일)
--- navbar
--- pages
---- page (data-page=home)
----- page-content
------ content-block
--- toolbar
---- tabbar 등등
-- view .foobar (만약 이 웹페이지가 아이패드 메모앱처럼 split된 화면을 가져야 할 경우 추가해서 사용함) - 그렇게 허탈하게 버그를 때려잡고 나니 힘이 빠져서, index.php의 대표이미지들 위에 그라데이션을 뿌린다든가 하는 세부적인 스타일링을 트윅하며 기운을 되찾음.
- 2일째에 정신없이 문서 읽고 깃헙 레포 뒤지다가 문득 발견한 것이 있어 "음 그럼 해볼까?" 하고 footer.php에 넣어둔 포토뷰어 JS 변수를 건드려봄. 'Close'를 '닫기'로 고치는 게 생각보다 너무 간단하게 되었다. photos 배열 넣는 배열 자리에 원하는 변수명의 값을 새로 지정해준 것만으로 적용이 됨. (이걸 간단한 일로 만들어준 개발자가 대단한 거다…)
- 최종 점검 마치고, 아이패드/아이폰 뷰 체크한 다음 최종본으로 발행.
교훈
- Framework 7은 앱 개발을 하는 기분으로 모바일웹을 개발하는 도구이다. 단순 컴포넌트 CSS를 묶어서 이쁘게 만들어주는 정도가 아니라, 각 개별 페이지들이 웹앱으로 작동하도록 AJAX로 처리한다.
- 따라서 Framework 7을 쓰려면 get 파라미터 대신 URL 라우팅과 data-page에 신경을 쓸 것이며, 막무가내로 아무데나 컴포넌트를 끌어다 쓰면 안 된다(요소들 위치 정해져 있는 정도가 꽤 까다롭다). 가급적 문서를 처음부터 천천히 읽고 제대로 개념을 이해한 다음 쓰기. 나처럼 실전 case위주로 막덤비면 공부도 안되고 효율도 떨어진다.
- 모바일 브로셔는 무료호스팅으로도 유지 가능한 트래픽을 자랑한다. (…) 여러분 올해가 가기 전에 코엑스 B홀 앞에 가 보세요!
'1 내 > ㅎ 열외' 카테고리의 다른 글
닷홈에 라라벨 설치하기 (7) | 2018.04.09 |
---|---|
세상에서 가장 무식하게 React 써보기 (0) | 2018.01.07 |
새 블로그 스킨 작업중! (0) | 2015.03.05 |
fontclub, font.co.kr 미리보기 렌더러 스펙 (4) | 2014.01.31 |
⊥ED Conference (0) | 2013.05.19 |