...+135+30
=556,347


이 글은 수시로 업데이트하는 기술 공부 블로그 포스팅입니다. 이런거 공유하면 확실히 낚여줄 내주변 지인이 최소 1명 있긴 한데... 그에게는 이글이 대윾잼+대환장 띠용글로 보일것이지만 알고도 굳이 씁니다. 목표는 1년뒤 나역시 이걸 보며 대윾잼+대환장을 느끼는것


0. 서론

머 아무튼 2017년도 다 저물어가는 마당에 호주 워홀 마치고 돌아와서 취직은 해야겠고 마땅히 벌어놓은 것이라고는 각종 기획의 잔꾀와 워드프레스/코드이그나이터[각주:1]로 좀 굴러본 것뿐인지라… 최소한의 최신 기술과 개념을 익혀놓지 않으면 안 되겠다는 약간의 절박함이 생겨, 귀국 후 크리스마스 이브에 과감하게 세팅하고 시작한 것이 yuptogun.com 프로젝트.

지금까지 걍 구상만 했던 각종 웹앱들을 *.yuptogun.com 형태의 서브도메인 아래에서 각기 구현해서 돌리고, 개중 잘 팔리는 게 생기면 별도 도메인으로 독립시켜서 운영하고, 그러면서 호스팅업체 서버 스택 아래에서 할 수 있는 최대한의 신기술&신개념을 막 도입해 써보는 운동장으로 쓸 계획.[각주:2]


1. 스택: shared LAMP stack hosting + Codeigniter + uncompiled (in-browser) React

A. 서버 스펙. 일단 주어진 서버 환경을 서술하자면... 전형적인 한국 PHP 웹호스팅 스택. 리눅스에 아파치와 MySQL을 깔고 PHP를 상시 켜놓으며 가상 할당 공간에 실행&전송할 파일을 올리는 방식이다. 월 5천 원을 더 내면 SSH 접속을 시켜준다고 하지만 지금은 그마저도 하고 있지 않아서 그야말로 20세기 FTP 홈페이지 스타일. 쉘접속이고 서버설정이고 그딴거ㅇ벗다.

AWS도 있고 다른 옵션도 많은데 굳이 이걸 선택한 이유는 딱 두가지.

  • 비용: 닷홈의 혜자급 상품으로, 도메인값만 닷홈에 내면 디스크 1G와 트래픽 무제한 이용이 무료로 가능하다. 써보다가 트래픽이 증가하면 상위 상품으로 올릴수있음. (물론 하위 상품으로 다운그레이드는 안된다)
  • 시장 친숙성: 서비스 자체를 서비스하는 IT 기업을 제외하면 나의 '클라이언트'가 될 사람들은 보통 shared web hosting 환경에서 뭔가를 하려고 한다.[각주:3] 따라서 임대형 쉐어 웹호스팅 환경이라는 (프로그래머에게는) 꽤 열악한 스택을 선택하기로 함.

B. 프레임워크. PHP라는 서버 언어가 주어진 상황에서 제일 최신 프레임웍을 써볼라치면 아무래도 라라벨이나 심포니 같은 걸 해야겠지? 아니면 좀 힙하게 Slim? 사실 호주에 있을 때 이것저것 건드려 봤는데 결국은 그간 해왔던 코드이그나이터를 골랐다.

  • 가볍다. PSL-7을 준수하는 프레임워크들은 FTP로 배치하는 것이 사실상 불가능하다. 파일이 보통 많아야 말이지. 로컬에서 작업한 걸 통째로 zip으로 묶어 그걸 올리고 unzip을 (쉘로 하건 php코드로 하건) 실행하는 게 그나마 the best practice so far더라.[각주:4]
  • 버전 관리를 할 것이 없다. Ion Auth나 TCPDF 말고는 딱히 더 갖다 쓸 서드파티 라이브러리도 없고, 대부분의 요소들은 어차피 사용자단에서 돌아가야 하는 파일들인지라 그냥 CDN에서 퍼와도 되겠다고 판단했다.
  • Slim은 라우팅까지 성공했고 라라벨은 배치하는 것까지 성공했으나[각주:5] 지금은 백엔드 로직보다는 프론트엔드의 react 공부에 집중하고 싶어서 경험이 있는 Codeigniter를 채택. 보아하니 아직은 코드이그나이터가 php 실무 바닥에서는 현역인 듯도 하고.
  • 뭐 말이 Codeigniter지 가급적 API 생성기로만 사용하고, 각종 라이브러리나 유틸리티는 서버에서 돌아가는 게 효율적일 때(세션관리 등)만 쓸 예정. 애초에 서버란 JSON만 송수신해주면 되는거니까.

C. 뷰처리. 여기서부터 모험이 시작된다. views/template/react.php 파일을 만들고 여기에서 reactjs cdn이라고 검색해서 나오는 파일 두 개와 babel cdn이라고 검색해서 나오는 파일 하나를 불러오게 시켜놨다.

  • 사실 React 생태계가 추구하는 방식대로 하자면 절대 이렇게 해서는 안 된다. 특히 Babel은 내가 짠 text/babel 스크립트 파일을 서버에서 미리 컴파일하는 데 쓰여야 하지, 브라우저에서 낑낑거리면서 실행할 물건이 아니다.
  • 그치만 뭐 일단은 콘솔에 인포 메시지 하나 뜨는 거랑 깜박임 문제[각주:6] 말고는 기능상 별 문제를 모르겠어서 그냥 넘어가고 있는중.


2. 기본 흐름: CI는 json과 뷰파일 목록만 구성하고 나머지는 React가 한다

메인페이지를 만들면서 결정한 설계는 다음과 같음.

  1. 기본 라우팅에 따라 컨트롤러가 실행된다.
  2. 컨트롤러는 다음 세 가지를 주로 실행한다.
    • 로딩될 뷰파일을 결정한다.
    • 뷰파일에서 사용할 데이터를 만든다. SEO용 메타태그, 현재 로그인한 회원 정보 등
    • 뷰파일에서 json으로 출력할 배열을 만든다. 필요한 DB 테이블 쿼리 결과를 json_encode()로 뽑아 $this->data['table'] 형태로 넘긴다.
  3. 메인뷰는 다음 세 가지를 실행한다.
    • 컨트롤러가 넘긴 데이터를 가지고 html 마크업을 뿌린다. 메타태그, 로그인했을 경우와 아닐경우에 따른 html 마크업 등등
    • 컨트롤러에게서 물려받은 json을 스크립트 태그로 html 출력 맨끝에 뿌린다.
      <script>var theData = <?= $data; ?>;</script>
    • 그리고 assets들(React 라이브러리, 메인 js, 각종 CSS 등등)을 불러온다.
  4. 그러면 이제 뷰가 불러온 메인 js 파일은 브라우저 안에서 다음과 같이 작동한다.
    • 메인뷰가 서버 응답으로서 돌려주는 DB 데이터 json을 props/state로 참조한다.
    • 이 props/state와 자기 안에서 const로 규정돼 있는 정적 정보들(e.g. 쿼리결과 없을시 뿌릴 문자열들 등)을 이용해, 엽토군이 정의한 대로 열심히 컴포넌트 클래스들을 렌더링한다.
장황하게 적었지만 코드를 보면 아주 간단한 이야기다. 해당 페이지의 응답결과는 예컨대 위쪽에 <script src="app.js">가 있고, 중간에 <div id="wrapper"></div> 같은 텅 빈 요소가 하나 있으며 그 밑으로 조금 내려가서 보면 아주 장황하게 긴 json을 data 변수에 할당한 script가 한두 개 있는 식이다. 그리고 app.js는 data.table.forEach((record) => {어쩌고저쩌고}) 형태의 라인을 가진다.
어떤 assets을 불러올 것인지를 뷰에서 결정할 것인가 컨트롤러에서 결정할 것인가는 지금은 좀 가닥 안잡혀서 일단 죄다 뷰에서 결정중. 아마 컨트롤러에 다 때려넣는게 더 말은 맞겠지(극단적으로 말해서 뷰파일은 그냥 div#app 하나만 덜렁 갖고있어도 될지도 모른다).


3. 깨달은 것들: React

React를 막무가내로 공식문서 봐가면서 공부하고 적용해 현재까지 깨달은 것들은 다음과 같다.
  • 만약 당신이 MVC 구조에 익숙하고, 새로운 라이브러리의 문법을 배우는 데 큰 문제가 없으며, 지금 당장은 리액트를 가지고 화면에 DB자료를 뿌리는 정도로 충분하다면, 다른 것보다 Thinking in React를 따라가는 것이 가장 좋고 가장 빠르다. 당신이 알아야 할 것은 거의 대부분 나와 있으며, props와 state 개념을 실전으로 바로 알 수 있다. 장황하게 createClass가 어쩌고저쩌고 하는 설명도 생략돼 있어, 필요한 기초에 집중할 수 있다.
  • state는 최상위 컴포넌트에서 통제되어야 한다. 글로 읽을 땐 영 뭔말인지 몰랐는데 실전을 해 보니까 간신히 이해가 되더라.
    예컨대 이런 상황이 있다고 생각해 보자.
#wrapper가 #sidebar와 #content의 2개 요소를 가지고 있고, #sidebar 밑의 a[data-tab=x]를 누르면 #content 밑의 #x가 보여야 함

jQuery라면 구현 자체는 아주 간단하다. .data('tab')으로 x값 얻어와서 $('#content')를 통제할 때 그 값을 넘기면 된다. 하지만 이 구현이 일으키는 변화는 필연적인 것이 전혀 아니며 오히려 아주 우연하고 작위적이다.
이 상황을 React는 이렇게 해결한다.

#wrapper는 #sidebar 밑의 a에 대해서도 책임이 있고, #content 밑의 div들에 대해서도 책임이 있다. 따라서 #wrapper의 this.state.tab을 정의해 주고, #content는 항상 이 state에 대응하는 div를 보여주도록 한 다음, #sidebar 밑의 a가 눌릴 때는 #wrapper의 this.state.tab이 적절히 업데이트되도록 한다. 그러면, #content 밑의 div는 즉시 자동으로 그 state에 반응("react")한다!

이렇게 써놓고 보니 왜 다들 그렇게 열광하는지 알것도 같음. 데이터가 어디로 흐르는지 볼 수 있고 훨씬 더 논리적이다. (단 그만큼 프론트엔드가 초반에 머리 싸매고 시작을 해야 하는 것. 어느 객체가 최상위인가? 정말 모두 한 개의 파일/스크립트 안에 넣어야 할까?)

  • 문자열을 직접 인젝션하는 코딩은 잘 안 된다. 예컨대 html 마크업을 구성하는 문자열은 이스케이프되어 문자그대로 브라우저에 뿌려진다. 정 그걸 띄우고 싶다면 악명높은 dangerouslysetinnerhtml을 쓰든지 차라리 리액트 html 오브젝트로 넣어버리라는 것이 공식 조언이다.
    또 남들은 다 된다고 하는데 나만 안 되는 것이 뭐나면… 문자열을 전달받아 그 문자열과 일치하는 이름의 컴포넌트 렌더링하기. 흔히 알려진 React.createElement(ChildName, null) 용법이 작동을 안 한다.[각주:7]
  • render () 메소드 내에서 const로 만드는 빈 배열은 길이가 0이 아니라 1이다. 이유는 모르겠다. 그래서 forEach push로 필터링을 할 때 결론적으로 이런 식의 이상한 판별식을 쓰고 있다. 이게 아닌데... 분명 더 옳은 방법이 있는데...
if (filteredArray[0].props.name != '') { /* do the stuff */ }
  • PHP가 세션/쿠키를 만드는 과정/방법론 때문에 사용자 인증이 생각보다 번거롭다. Ion Auth를 쓰고 있는데, 최종적으로는 기껏 깔아놓은 react router를 못쓰고 결국 자기 자신에게 로그인폼을 POST 제출해서 로그인 처리하고 리디렉션 시키는 몹시 전통적인 짓을 하고 있다.
    • 원래 계획은 ajax 폼으로 그 자리에서 즉각 로그인을 시키는 것이었다. 로그인 자체는 성공했는데, 문제는 자동로그인("keep logged in") 기능. 자동로그인이 도무지 먹지를 않는다. 왜 그런가 하고 모든 소스를 다 뜯어본 결과… "자동로그인"은 일반적으로 이런 로직으로 동작한다는 것을 알았다.
    1. 사용자가 POST 요청으로 로그인을 시도한다.
    2. PHP는 ID, 해싱된 패스워드, 자동로그인 여부를 받아 로그인(유저정보 매칭)을 시도한다.
    3. 로그인이 성공하면 PHP는 지금 로그인한 세션 고유값을 DB에 저장한다.
    4. 그리고 즉시 HTTP 응답 헤더에 이 세션 고유값이 포함된 쿠키를 쓰라는 요청을 보내는 리디렉션을 실행한다.
    5. 이때 PHP가 별다른 출력을 내지 않아야 비로소 이 쿠키가 써진다.[각주:8]
    6. 리디렉션된 HTTP 응답에서부터 쿠키와 세션은 유효해진다.
    7. 그래서 그 다음부터 (리액트 라우터가 아닌) PHP가 HTTP 요청을 받으면 우선 서버단에서 쿠키와 세션을 확인해 로그인 여부를 체크하고 그제서야 그 결과를 반환해 이용할 수 있게 한다. 여기서 자동로그인 구현 완료.
    • 여기서 5번 스텝이 문제되는 것이었다. ajax 요청은 필연적으로 출력을 낳고, 따라서 자동로그인 로직의 5번에서 멈춘다.[각주:9]
    • 그러면 ajax 요청 콜백에서 적당히 쿠키를 만들면 되는것 아니냐? 싶을 텐데 그러면 7번 스텝이 걸림. 요컨대 자동로그인을 체크하고 로그인해서[각주:10] → 사용자 정보를 가져온 뷰를 → F5로 새로고침하면[각주:11] → 거짓말처럼 로그아웃당함.[각주:12]
    • 서버단이 JS로만 구현되었거나 자동로그인 로직이 좀 달랐다면[각주:13] ajax 콜백의 쿠키 작성만으로도 충분히 자동로그인을 할 수 있었을까 하는 미련이 남지만... 그건 먼 훗날 많은 이치를 깨닫고 나서 다시 보기로. 지금은 우선 로그인을 시켰다는 데 의의를 두면서, u/(.*) 라우팅과 컨트롤러의 u() 통제와 users.js 최적화로 타협한다.[각주:14]

99. 해야될것들

  1. Redux 배워서 써먹기
    • "최상위 컴포넌트에 스테이트 때려박는게 너무 귀찮아서 온갖 방법으로 그걸 회피하는데요 그래서 state management 라이브러리를 씁니다...!"
    • 아직은 귀찮거나 헤비하지 않지만 넘나 당연하게 react의 짝패로 쓰이는 모양이니 싫어도 적용해야할듯.
  2. webpack 배워서 써먹(으면서 필요한 의존성 버전관리하)기
    • "근데 리액트 사용의 정석은 php 파일에서 로드하는거는 아니에요 webpack으로 빌드해서 index.html 및 js / assets 뭉치를 만들고 걔를 static hosting"[각주:15]
    • 지금 당장은 이런 스텝들이 필요할듯
      • React, Babel을 npm으로 받아서 로컬 트리에 넣어놓기
      • 지금 있는 메인 js를 번들 가능하게 조정하기
      • 컨트롤러 $dev 변수에 따라서 지금식으로 다 로드하느냐 bundle-*.js만 불러오느냐를 스위칭할 수 있게. (이건 순 내 편의를 위한 편법. 충격적이게도 지금은 메인 js 고칠때마다 서버에 업로드하고 새로고침을 해서 테스트를 본다고 한다...)
    • 뭐 일단 해놓으면 앞으로는 npm update 한번씩만 돌리면 되겠지
      • 잘은 몰라도 나중되면 지금 뷰파일이 로딩중인 fontAwesome, pureCSS 등등도 죄다 이걸로 관리하게될듯


  1. 그리고 대략 다섯 달 동안이지만 충격과 공포의 해피CGI 솔루션(...)을 경험해봤다. PHP 5.2 이하에서 실행해 달라고 요구하는 솔루션을 들어보신 적이 있는지? 한국에서는 무려 이새끼가 아직도 현역이다. 팩트TV가 이회사 물건으로 돌아가고 있다. [본문으로]
  2. 어차피 만들려는 웹앱들의 본질이 TODO를 크게 벗어나지 않기 때문에 가능한 짓이다. [본문으로]
  3. 보통은 애초에 "서버언어" 개념 자체를 안 갖고 계시니. [본문으로]
  4. 예전의 다른 웹호스팅에 라라벨 올리면서 찾은 방법. 다시 하기는 싫다. [본문으로]
  5. 일단 로컬 구조 그대로 올린다 → 루트의 index.php가 public/index.php 를 require하도록 고친다 → public/index.php 가 ../bootstrap/autoload.php 와 ../bootstrap/app.php 를 require하도록 한다. 이렇게 하면 FTP만 되는 호스팅 환경에서도 일단 라라벨을 굴릴 수는 있음. [본문으로]
  6. 인브라우저 컴파일 중일 때는 아무것도 안 뜨다가 잠시 후에야 가상DOM이 그려지는 문제. 리액트 사용상의 대표적인 대환장 포인트 중 하나라고. [본문으로]
  7. 선배왈 스위치문 써서 컴포넌트 리턴하는 거 말고는 답이 없다고. 안그래도 나도지금 그렇게 하는중이다. 글쎄 이게 아닌데... [본문으로]
  8. 내가 이해한 바로는, 쿠키 생성 코드가 포함된 코드 라인들의 최종 목적이 '뭔가를 출력하는 것'이어서는 안 된다는 느낌이다. 예컨대 redirect()는 괜찮지만 return $resultjson은 안 된다. [본문으로]
  9. 별짓을 다해 확인해 본 결과, 세션도 만들어지고 쿠키 요청도 들어가지만 실제 쿠키 생성부터가 안된다는 것으로 판명. CORS도 확인하고 별짓을 다해봤는데 그게 문제가 아니라 결국 setcookie() 함수의 결함이랄까 설계 때문에 안된다. [본문으로]
  10. 여기선 클라이언트(브라우저)가 단지 쿠키만을 작성한다. [본문으로]
  11. 여기선 서버가 존재하지 않는 로그인정보 세션을 체크하려고 시도한다. [본문으로]
  12. 매치해 볼 세션이 없으므로 자명한 결과. [본문으로]
  13. 대충 찾아보니 JWT(JSON 웹토큰)과 로컬스토리지 사용이 JS 환경에서는 가장 통념으로 사용되는 듯하다. [본문으로]
  14. 그리고 (서버와 리액트가 라우팅을 놓고 싸우는 탓에) 꽤 속도가 느려졌으며 여전히 두세 시간 뒤면 세션이 풀려버린다. 왜죠... [본문으로]
  15. 느닷없이 그런 말을 들어도 지금은 잘모르겠는 부분이지만 여튼 이바닥 선배가 그렇다고 하니 그런줄 알자. [본문으로]
Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

주어진 임무:

10팀의 아티스트가 만든 10개의 전시물에 대해 국문/영문 소개문, 사진, 아티스트 소개 등을 보여주는 그럴듯한 모바일 브로셔를 만들어라.


실제 돌아가는 결과물: upcyclingtree.dothome.co.kr


전체 소스:

github.com/yuptogun/Upcycling-Tree-Mobile-Flyer




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홀 앞에 가 보세요!


Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

스킨 이름은 아직 안 정해졌습니다. 일단 개인용입니다. 색은 뭐 그냥 랜덤하게 뽑다 보니 미묘한 금색이 뽑혔습니다.



LIVE DEMO 보기




기본 화면일단 기본적으로 이렇게 생겼습니다.


일반 메뉴팝업메뉴 버튼을 누르면 메뉴가 뽑혀 나옵니다.


코멘트 입력란코멘트나 트랙백 넣는 곳은 이렇게 생겼습니다. 크 누가 만들었는지 겁나 이쁘다.


아이폰 가로모드 기본화면아이폰 가로모드 등의 환경도 완벽하게 지원(하려고 )합니다.


아이폰 가로모드 메뉴팝업메뉴 버튼을 누르면 상단 고정 메뉴가 쭈르륵 내려옵니다.




사용된 외부 리소스:

  • pureCSS (grids, buttons, forms)
  • jQuery + jQuery UI
  • FontAwesome


남은 작업:

  • 트랙백/코멘트 수 표시, 각종 로그페이지 구현(을 할 것인지 어떤지 결정하기)
  • 공유 버튼 추가
  • 기본 메뉴가 지나치게 길 경우에 대한 가로/세로 레이아웃 대책마련 (overflow: scroll 이란게 구체적으로 어떻게 먹히는건지 알아보고 구현할 필요)
  • footer에 이것저것 몰아넣기
  • 실제 태터툴즈 구조에 맞도록 id, class 조정 ← 서로 엉키지 말아야할텐데…
  • 최종적으로는 마크쿼리 스킨과의 차별성 확보. 사실 좀더 어그레시브하게 짜고 싶은 요소들이 많았는데 그렇게 하면 indication 내지 direction이 안될거같아 그냥 좀더 노멀하게 가고 있다. 아작스 로딩화면이니 첫화면 슬라이드니 하는 거창한 것들은, 이게 내 블로그를 위한 작업이지 남을 위한 것은 아직 아니므로, 일단은 구현하지 않을 생각.


이 블로그 스킨도 사실 꿰매고 기운 곳이 많아서... 이제 곧 싹 갈아엎은 이쁜 블로그 스킨으로 찾아뵐 수 있을 것 같습니다. 기대하시라 ㅋㅋ

Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

쓸만한 한글웹폰트가 왤케 없나 (그래서 예전엔 내가 아예 하나 만들었지만... 이젠 웹환경이 달라져서 그딴걸로는 택도 없다. -_-;) 싶어서 둘러보며 소스 뜯어보다가 혹시나 이게 img 태그로 먹히나 해서 보니 먹힘. 그래서 올려봅니다.



1. 폰트클럽 (산돌)

ReturnFontTextImage.asp

fontclub.co.kr의 폰트샵에서 사용하는 폰트 미리보기 서비스 코드. 적절한 파라미터 값을 주면 이미지를 반환한다.


(현재까지 알려진) 파라미터

FontName
사용될 폰트 이름. EUC-KR 인코딩. 유효한 값은 폰트샵 각개 폰트 미리보기 이미지 URL을 복사해서 해당 파라미터 부분 보고 찾으면 됨.


FontImageText
출력할 문자열. EUC-KR 인코딩.


FontSize
출력될 문자열의 크기. 자연수. 기본값은 24. 픽셀 단위는 아닌 듯.
출력되는 문자열 위에 빈 공간이 붙기 때문에 이 변수가 ImageHeight 변수보다 20% 정도 더 작지 않을 경우 글자 아랫단이 잘린다.


ImageWidth, ImageHeight
각각 문자열을 출력할 이미지의 가로 및 세로 크기. 이 캔버스 안에 들어오지 않는 문자열은 잘린다.

예제

http://shop.fontclub.co.kr/include/font/ReturnFontTextImage.asp?FontImageText=%C0%DF%B5%C7%B4%C2%C1%F6%BA%B8%B0%DA%BD%C0%B4%CF%B4%D9&FontSize=50&ImageWidth=720&ImageHeight=65&FontName=210%20%C4%DE%C7%BB%C5%B8%BC%BC%C5%B9%20B



2. font.co.kr (윤디자인)

preview.aspx

font.co.kr의 폰트샵에서 사용하는 폰트 미리보기 서비스 코드. 적절한 파라미터 값을 주면 이미지를 반환한다.


(현재까지 알려진) 파라미터

fontname
사용될 폰트 이름. 일반 URL 인코딩. 유효한 값은 폰트샵 각개 폰트 미리보기 이미지 URL을 복사해서 해당 파라미터 부분 보고 찾으면 됨.


text
출력할 문자열. 일반 URL 인코딩.


fontsize

출력될 문자열의 크기. 자연수. 기본값 없음, 0 이상의 자연수를 무조건 넣어야 함.
어떤 이유인지 모르겠지만 height 값의 0.85배(추측)보다 fontsize 값이 클 경우 출력 자체가 되지 않는다.


width, height
각각 문자열을 출력할 이미지의 가로 및
 세로 크기. 이 캔버스 안에 들어오지 않는 문자열은 잘린다.

예제

http://generatorutf8.font.co.kr/preview2/yoonfont/preview.aspx?text=%EC%9E%98%EB%90%98%EB%8A%94%EC%A7%80%EB%B3%B4%EA%B2%A0%EC%8A%B5%EB%8B%88%EB%8B%A4&fontname=Yoon%EC%9C%A4%EA%B3%A0%EB%94%95%20710&fontsize=40&width=350&height=47



뭐 고수분들은 이 정도 소스만 가지고도 이리저리 잘 활용하실 수 있을 것 같긴 한데...

코드는 윤이 좀더 좋고 선택 범위는 산돌이 훨씬 넓네요. 어떻게 하면 잘 훔쳐쓸 수 있을까

Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  1. bleu1115
    2016.05.26 10:20 신고
    댓글 주소 수정/삭제 댓글
    첫번째 산돌 이미지는 깨져서 나오는데
    이제 저 방식으로 사용할 수 없는 걸까요?
    • 2016.05.27 10:03 신고
      댓글 주소 수정/삭제
      아 폰트샵 주소가 바뀌었네요. 수정넣었습니다.
      사실 산돌폰트는 sandollcloud.com 서비스를 가입해서 쓰는게 비용대비 제일 효율이 높습니다.
  2. bleu1115
    2016.05.27 16:05 신고
    댓글 주소 수정/삭제 댓글
    오.. 잘 되는군요! 감사합니다. ㅎㅎ

모든 아이디어가 퍼뜨릴 만한 가치가 있는 것은 아니다. Not every idea is worth spreading.


"아프니까 청춘이다", "당신이 사는 곳이 당신이 누구인지 말해 줍니다" 등 누가 들어도 잘못된 말과 사고방식과 아이디어에 우리가 일상적으로 노출되어 있다는 사실은, 이 글을 읽고 있는 누구나 알고 있다.
그러나 생태주의는 어떠한가? '서바이벌' 쇼는 어떠한가? 유비쿼터스 세계는 어떠한가? 지금의 세계화는 무조건 옳은가? 기발하고 참신하다는 이유로 극악한 신종 범죄의 수법을 굳이 뉴스로 선전해야만 하는가? 왜 모든 기술(Technology)과 교육(Education)과 디자인(Design)은 그 존재 자체로 비판의 대상이 되지 않는가? 진흙으로 벽돌을 굽는다는 '기술', 모두의 언어를 하나로 모으는 '교육', 하늘 꼭대기에 닿게 탑을 쌓는다는 '디자인'은 결국 무엇을 건축하였던가? 인류에겐 바벨탑이 한 번으로는 부족하였는가?

우리는 의심하고 비판하고 재고하고자 한다.
⊥ED 컨퍼런스는 바로 이 일을 할 것이다. 오늘날 TED 컨퍼런스로 대표되는 "아이디어는 무조건 확산해야만 하는 것"이라는 하나의 교조(dogma)에 저항할 것이다. 수많은 아이디어에 사회적, 역사적, 윤리적 책임을 부여할 것이다. 모두 다 옳고 좋아 보이던 아이디어들 사이에서 모순(⊥)을 점검할 것이다.

청춘이기 위해 아파야 하며, 내가 누구인지 말하기 위해 내가 어디에 사는지를 따져야 하며, 어디서부터 무엇이 잘못되었는지조차 알지 못한 채 화려하고 세련돼 보이는 최신 유행을 따른 죄로 '하여간 뭔가 분명히 크게 잘못된' 세상을 살고 싶지 않다면,
⊥ED conference에 참여하라.

Eojin Kim
Founder
yuptogun@gmail.com


⊥ED Conference가 기본적으로 추진할 일들입니다.

1. ⊥ED 컨퍼런스
뭔가 미심쩍고 잘못된 것 같은데 아무도 문제를 제기하지 않는 각종 현상과 슬로건과 '상식'에 의문을 제기하는 5~10분 분량의 강연을 듣고, 연사와 청중이 거침없이 문답을 주고받는 자리입니다. ⊥ED 컨퍼런스의 핵심 행사지요. TED 컨퍼런스가 연사와 청중을 까다로운 기준으로 선정해서 초대한다면, ⊥ED 컨퍼런스는 여러분을 초대합니다! 청중이 되어 가장 날카로운 질문을 던지거나, 연사가 되어 가장 강력한 의문을 제기하세요!

2. Video Podcasting
⊥ED 컨퍼런스의 실황을 촬영하여 YouTube, Vimeo 그리고 팟캐스트로 내보낼 것입니다. 10분을 넘지 않는 시간 동안 한 번도 의문시해 보지 못했던 것들을 의문시하게 하는 무료 비디오 프로그램입니다! 이게 진짜로 세상을 바꾸는 아이디어의 시작 아니겠습니까? 아닌 것을 아니라고 말하는 비디오가 얼마나 빠르고 강력하게 얼마나 많은 사람에게 영향을 끼치는지, 우리는 직접 목격하게 될 것입니다.

여건과 조직을 갖추면 이런 일들도 추진하고자 합니다.

3. 간행본 출판
서점 베스트셀러 진열대에 가 보십시오. 모든 책이 너나할 것 없이 자기가 유일한 정답이며 해결책이라고 아웅다웅하고 있습니다. 사실, ⊥ED Conference는 그 현상 자체에도 의문을 제기할 수 있을 것입니다! 그렇다면 <⊥ED Conference Opus '13> 같은 책이야말로 언제나 꾸준히 탐독될 만한 충분한 자격이 있는 책이 되지 않을까요? 강연 내용을 전체 수록하고, 연사와 각계 전문가 여러분의 감수를 거친 좀더 심도 있는 논의 등을 충분히 수록하여 꾸준히 발행한다면, 인류에 공헌하는 바가 있을 것입니다.

4. 대안을 실현하기(Kick-starting)

"A는 잘못됐다, A는 B가 되어야 마땅하다"라는 강연을 듣고 크게 감동하셨다고요? 그리고 정말로 A를 B로 만드는 것도 생각해 보니 그다지 어렵지 않을 것 같다고요? 아마 대부분의 의문 제기가―TED처럼 거창한 최첨단의 기술과 디자인과 상관없기 때문에―실현하기 쉬울 것입니다! ⊥ED 컨퍼런스는 의문을 주고받으며 비판하는 것을 넘어서서, 굳이 최첨단과 최대 규모일 필요가 없는 수많은 대안들을 제안할 것이고, ⊥ED Conference의 이름으로 그와 관련된 사업 착수를 지원할 것입니다.


⊥ED Conference의 연사가 되기 위한 다섯 단계입니다.

1. "아무도 문제제기를 하지 않는 어떤 것"에 대한 불만과 의문을 떠올려 보세요. 잘못된 사회 통념, 불쾌하게 유행하는 말과 행동, 나 빼고 모두가 당연하게 여기고 있는데 도무지 왜 당연한지 알 수 없는 것들을 생각해 보시면 됩니다. 이것이 보통 강연의 서론이 됩니다.

2. '나는 왜 그것이 불만일까?' 또는 '그것의 정체와 실상은 이러이러한 게 아닐까?'에 대한 답을 만들어 주세요. 달리 표현하자면 그 불만의 근원 또는 그 의심스러운 것의 정체를 폭로하는 것입니다. 논리적·학문적으로 완벽하지 않아도 좋습니다. 당신이 느끼는 그대로를 최대한 끌어내십시오. 이것이 보통 강연의 본론이 됩니다.

3. "그것을 대체해야 할 최선의 방안"을 반드시 제시해 주세요. 허황되거나 이상주의적이어도 괜찮습니다. 청중을 한번 크게 웃기는 '개드립'도 아주 좋습니다. 하여간 대안은 반드시 필요합니다. 이것이 보통 강연의 결론이 되기 때문입니다.

4. 이 세 가지를 최소 3분, 최대 10분 이내에 전달할 수 있도록 정리해 주세요. 저희는 TED와 같은 유창한 화술과 스펙터클한 프리젠테이션에는 관심이 없습니다. ⊥ED 컨퍼런스의 최대 관심사는, 당신의 불만과 의문이 얼마나 날카롭고 솔직하고 전면적인가입니다.

5. 여기까지 다 준비하셨다면 yuptogun@Gmail.com으로 강연 취지와 원고가 담긴 전자우편을 전송해 주십시오. ⊥ED의 면밀한 검토와 협의 후에, 당신은 머지않아 컨퍼런스에서 가장 중요한 연사로서 단상에 초청될 것입니다.

아닌 것을 아니라고 말하세요. ⊥ED Conference의 연사가 되세요. 얼마나 많은 사람들이 당신의 고발을 기다리고 있는지 모릅니다.


"⊥ED"를 읽는 방법은 자유입니다. 가장 형식적인 발음은 'falsumED'지만 크게 상관은 없습니다. 뒤집힌테드, 업택드, 모순드, prepED, 엿테드, 마음대로 부르셔도 좋습니다. 참고로 페이지 관리자는 폴숨드라는 발음 연습에 실패해서 결국 '역테드'라고 부르고 있습니다.

다만 문자표기는 정확하게 해 주시기 바랍니다! ⊥(폴숨)은 수학 기호(ㄷ+특수문자) 중에 있습니다. ㅗ로 ⊥을 대체하는 것은 허용하겠습니다.


너무 즉흥적으로 벌린 바람에 수습하지 못하고 일단 접은 기획. 더 깊게 생각할 시간이 필요합니다. 그렇게 생각을 해 보았는데도 아무래도 안 되겠다 싶으면 완전히 짬시킬 수도 있습니다.


'1 내 > ㅎ 열외' 카테고리의 다른 글

새 블로그 스킨 작업중!  (0) 2015.03.05
fontclub, font.co.kr 미리보기 렌더러 스펙  (4) 2014.01.31
⊥ED Conference  (0) 2013.05.19
김어진정자10.ttf v2.9 업데이트  (7) 2013.04.19
dok.do 단축URL 생성 북마클릿 깔기  (0) 2013.03.30
공익광고  (0) 2011.09.27
Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

도대체 이게 얼마만이야!!!



안녕하세요, 2003년에 김어진정자10이라는 웹폰트를 내놓았던 엽토군입니다. (그땐 중3이었지...)

정확히 10년만의 업데이트를 들고 돌아왔습니다.



(jeongja10.ttf가 해당 파일입니다.

보이지 않으시면 여기로→ https://www.box.com/s/3ro1hwuxy8yvwegk4e1e)


v2.9 업데이트 내역

글립(자소) 7개가 추가되었습니다. 눝, 늍, 똠, 쎼, 쎾, 쑛, 찦

일부 자소의 kerning 및 정밀화를 실시했습니다.


배포는 오직 이곳에서만 이루어져야 합니다. 위의 box.net 링크 또는 이 홈페이지(yuptogun.tistory.com)을 중개하는 방식 외의 "다운받아 다른 곳에 재첨부하기", "직접 다른 사람에게 복사해주기" 등등을 일체 엄금합니다. 그 외의 거의 대부분의 사용은 자유입니다. 누가 만들었는지 확실하게 하고 싶어서 저작권자가 요구하는 최소한의 제약조건이오니 부디 지켜 주십시오.


v3.0 업데이트 예고

완성형에서 조합형으로의 확장 이전을 단행합니다. (11172자를 전부 쓰실 수 있게 됩니다.)




잡썰


'1 내 > ㅎ 열외' 카테고리의 다른 글

fontclub, font.co.kr 미리보기 렌더러 스펙  (4) 2014.01.31
⊥ED Conference  (0) 2013.05.19
김어진정자10.ttf v2.9 업데이트  (7) 2013.04.19
dok.do 단축URL 생성 북마클릿 깔기  (0) 2013.03.30
공익광고  (0) 2011.09.27
랜덤게임 아이디어 "나는 뭔데?!"  (0) 2010.05.01
Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  1. 헐...
    2013.05.30 14:27 신고
    댓글 주소 수정/삭제 댓글
    대박이네요.ㅎㅎㅎ
    얼마전에 저작권 폰트 정리 좀 하다가
    출처를 알 수 없거나, 혹은 출처가 사라졌거나 했던 폰트들이 있어서
    이걸 상업적으로 사용해야하나 마나 고민하고 있었는데
    오늘 우연히 혹시 싶어 엽토체를 검색해보니 정~~말 오랜만에 업데이트가 나왔군요.ㅎㅎㅎ
    설마 아직까지 출처가 남아있을 줄은 몰랐네요.
    왠지 반가운 마음이 드는....ㅋㅋ
    • 2013.05.31 00:53 신고
      댓글 주소 수정/삭제
      ㅋㅋㅋㅋㅋ... 저도 이젠 이 폰트의 저작권을 제가 주장할 수 있다는 게 신기하답니다...
      방학 중에 두 서체를 완전 조합형으로 전환시킬 계획입니다. 기억해 두셨다가 가끔 체크해 주세요! (사실 가장 해야 할 작업은 자연스러운 곡선으로 바꾸는 일이지만... ㅋㅋ)
  2. 2015.02.14 12:34
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
    • 2015.02.16 00:40 신고
      댓글 주소 수정/삭제
      감사합니다. 이런 사연들이 있어 뭐라도 열심히 해보자는 다짐이 새로 섭니다.
  3. 2016.03.19 03:30
    댓글 주소 수정/삭제 댓글
    비밀댓글입니다
    • 2016.03.20 09:07
      댓글 주소 수정/삭제
      비밀댓글입니다
    • 2016.03.21 11:42 신고
      댓글 주소 수정/삭제
      네 그렇게 쓰시라고 만든 폰트입니다. 자유롭게 사용하세요. (폰트 파일 자체로 수익을 내지만 않으면 됩니다.)

※ 현재 이 서비스를 지원하는 메조미디어가 서비스를 일시중단한 상태입니다.


dok.do라는 URL shortener(긴 주소 짧게 만드는 페이지)가 있습니다. (스팸문자 보내는 사람들이 악용하는가 보더군요.)

http://dok.do



웹으로 들어가서 줄이고 싶은 원래의 긴 주소를 입력하면 바꿔 주는데, 대부분의 URL 단축기들이 지원하는 북마클릿(bookmarklet)이 없길래 실망스러워하다가, 조사해 보니 만드는 게 어렵지 않다는 것 같아서 시도해 봤습니다. 난 자바도 소스 살짝 수정하는 것밖에 모르는데...


그리고 5분만에 해냈습니다!!!

-.-;;




Dok.do 즐겨찾기로 사용하기



1. 다음 자바스크립트 전체를 복사합니다. java 부터 text') 까지입니다.


javascript:void(location.href='http://dok.do/api/shorten?longUrl='+location.href+'&format=text')



2. 사용하고자 하는 브라우저에서 아무 페이지나 일단 즐겨찾기(북마크)합니다.


예를 들면 이렇게 1



3. 즐겨찾기 수정으로 들어가서 방금 즐겨찾기한 페이지의 URL(주소)를 방금 복사한 자바스크립트로 바꿔치기합니다. 페이지 타이틀도 원래의 제목에서 'dok.do로 줄이기' 같은 걸로 바꾸면 좋겠죠.


예를 들면 이렇게 2



4. 이제 앞으로 주소를 줄이고 싶은 페이지에서 수정한 그 즐겨찾기를 누르면 이렇게 작동이 됩니다.


예를 들면 이렇게 3



원래는 goo.gl을 가장 많이 썼는데, 이 방법을 직접 찾아낸 이상에는 저도 dok.do를 좀더 많이 써보려고 합니다. 작동 원활하게 잘 됩니다.

이 단축URL 서비스가 오래 가면 좋겠네요. dok.do의 about에 들어가 본 외국인들이 독도가 한국령인걸 좀 알길 바라며...

'1 내 > ㅎ 열외' 카테고리의 다른 글

⊥ED Conference  (0) 2013.05.19
김어진정자10.ttf v2.9 업데이트  (7) 2013.04.19
dok.do 단축URL 생성 북마클릿 깔기  (0) 2013.03.30
공익광고  (0) 2011.09.27
랜덤게임 아이디어 "나는 뭔데?!"  (0) 2010.05.01
근래 해본 사고들  (2) 2010.01.03
Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

공익광고

2011.09.27 22:53
좀 도와주십쇼
 


자세한 정보 및 공식연락처는↓
바로그텀블버그 모금일기(RSS) / 바로그트위터 / 바로그텀블러(블로그) 아니면 저한테 직접
Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

0. 이 글은 랜덤게임 '나는 뭔데?!'를 설명하기 위해 쓰는 글이다. 저녁점호 중에 '사랑해 병신'을 하다가 문득 생각해봤다.
1. (일반모드) 술래부터 오른쪽으로 돌아가면서 왼쪽 사람을 찍으면서 숫자를 1부터 하나씩 부른다. 그게 그 사람 번호이다.
(하드모드) 술래부터 오른쪽으로 돌아가면서 아무나 찍으면서 숫자를 1부터 하나씩 부른다. 찍힌 사람이 그 번호를 받는다. 단 같은 사람이 두 번 찍히면, 그는 두 번째로 자기를 찍은 사람에게 달려가 멱살을 잡고 "나는 뭔데?!"를 외치면 된다(멱살 잡힌 사람이 걸린 거임).
2. (일반모드) 다 돌아가면 술래부터 아무나 찍으면서 그의 번호를 부른다.
2. (하드모드) 다 돌아가면 술래부터 아무나 찍으면서 아무 번호나 부른다.
3. (일반모드) 찍힌 사람이 다시 아무나 찍으면서 그 사람의 번호를 부른다.
3. (하드모드)  '찍힌(번호 불린 사람 말고)' 사람이 다시 아무나 찍으면서 아무 번호나 부르되 방금 자기를 찍은 사람 번호를 부르면 안 된다. 그럴 경우 번호 불린 사람은 자기가 아까 찍었던 사람의 멱살을 잡고 "나는 뭔데?!"를 외쳐주면 된다. 번호 불린 사람이 다시 누굴 찍으려고 하면, 안 틀린 사람이 일어나서 틀린 사람 멱살을 잡고 "나는 뭔데?!"를 외쳐준다.
4. 걸리는 경우는 다음과 같다.
4. (일반모드) 누군가의 번호를 부르며 찍는데 번호가 틀릴 때(찍힌 사람이 일어나 자길 찍은 사람 멱살을 잡는다), 혼자 "쟤 틀린 거 아냐?"라고 반문하고 있을 때(옆사람이 그 얼간이의 멱살을 잡아주며 "쟤는 뭔데?!"라고 한다).
4. (하드모드) '번호를 불린' 사람이 혼자 누굴 또 찍고 있을 때, 혼자 누가 누군지 몰라 얼때릴 때.
5. 게임의 목적은 다양한 정체성을 실험해 보는 청년기의 질풍노도를 놀이로 체험하면서 자신의 정체성을 파악하고 다른 사람의 정체성을 이해하는 훈련을 하는 데 있는 게 아니라 그냥 미친듯이 헷갈리게 놀아보는 데 있다.
9. 너무 어려워서 개선이 필요하다.

Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  • 결국 'real'한 것이 중요하게 인식되고 사람들의 생각을 주름잡는다. 리얼하다는 것은 생생하다는 것이 아니라 '앎과 겪음의 일치'를 의미한다. "Really?"라고 되물을 때 이것은 "내가 알고 있는 그게 맞느냐?"라는 의미가 된다. 왜 영화관에서 그래픽으로 범벅이 된 장면을 볼 때 우리는 '리얼하다'고 느끼는가? 우리 머릿속에 있는 간접 경험들은 훨씬 과장되어 있고(앎), 영화의 장면 또한 그만큼 과장되어 있다(겪음)는 점에서 두 가지가 일치함으로써 리얼하다고 느끼는 것이다(실제로는 '생생함', '진짜 현실'의 수준보다 훨씬 더 부풀려져 있음에도 불구하고).
    신자유주의적 세계관 특히 IMF 이후 더욱 심각해진 '현실적인' 경제관 또한 이러한 관점에서 재고해볼 수 있다고 생각한다: 우리가 알고 있는 경제문제는 그만큼 심각한가? 과장되어 있지는 않은가? 현재 사람들 사이에서 신자유주의적 현실주의가 real한 것이 되어 있는데, 과연 그것은 현실주의가 현실이어서 그런가, 우리의 real이 이 미쳐 돌아가는 세상만큼 미쳐 있어서 그런 것인가 하는 질문이 가능하지 않은가?
    아무튼 '리얼' 논의는 해볼 만한 것 같다. 무엇인가가 우리에게 지나칠 정도로 리얼한 것으로 다가온다면 이것은 앎의 지나침 혹은 겪음의 지나침에서 오는 오류일 가능성이 크다. 실제는 real과 틀리다. 앎과 겪음은 모두 주관의 것이다. 완전히 객관화 가능한 주관적 판단은 불가하겠지만, real의 문제는 좀더 복잡하고 세세하게 다뤄볼 필요가 느껴진다.
  • 우리는 모든 것을 좀더 노골적으로 말할 필요가 있다. 멋진 개념어로 너무 꾸며놓으면 그것이 죄, 일탈, 잘못, 허물, 불의, 이상함, 오류, 무지, 무책임, 무의미라는 게 감각되지 않는다. 그런데 그런 것들이 주변에 널려 있다. 뭔가 멋진 말과 구실을 갖다붙이고 있다. 프레임의 문제인가. 아무튼 좀더 노골적인 표현을 써서 문제를 바라볼 필요가 있다. (물론 그 문제를 건설적으로 비판하고 해결하려면 노골화를 그만두어야 하지만 말이다. 형질이 빈빈이니까.)
  • 모든 사람을 위한, 모두가 공감하고 수용하는 '이론'은 없다. 있다면 그것은 이미 이론이 아니라 방법론적인 의미에서의 '사실'일 테지.
  • 작은 일에 충성하지 못하면 큰 일에도 충성하지 못한다.
    사람은 변하지 않는다. 변하는 건 그 사람의 행실뿐이다.
  • 난 이승훈 선수 팬 할 꺼야. 어떻게 만 미터를 달리지
  • TV의 기능은 크게 두 가지인 것 같다. watching과 showing이다. 시청자에게 뭘 보여주는 기능이 있고 시청자가 뭔가를 보게 해 주는 기능이 있다. 전자는 예능이고 후자는 교양이겠지
Posted by 엽토군

댓글을 달아주세요:: 네티켓은 기본, 스팸은 사절

  1. 2010.02.23 10:43 신고
    댓글 주소 수정/삭제 댓글
    어진아 전화해


카테고리

분류 전체보기 (776)
0 현재 호주워홀 (6)
1 내 (323)
2 다른 이들의 (251)
3 늘어놓은 (32)
4 생각을 놓은 (66)
5 외치는 (69)
9 도저히 분류못함 (28)

달력

«   2018/01   »
  1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31      
Statistics Graph