Facebook Comment 를 Disqus 로 내보내는 FB2Disqus

페이스북의 Social comment 를 잘 사용하고 있었지만, Disqus 로 옮기고 싶었다.

페이스북 사용자가 아니면 댓글을 달기 어려운 면이 있기 때문에 좀 더 확장하고 싶었다. 그리고 더 큰 이유는 디자인 이었다.

블로그를 새로 꾸미면서 블로그 글 영역을 가변폭으로 만들었는데 Facebook 의 social comment 는 고정폭 만 지원하고 있다. 그리고 페이스북의 댓글창보다는 Disqus 의 디자인이 더 아름다워 보이고 내 블로그에 더 잘 어울린다는 생각이 들었다.

Exporter 쯤은 있겠지 생각만 하고 있다 검색해보니 나오질 않아서 하나 만들게 되었다.

우선은 요즘 주로 사용하고 있는 Coffeescript 로 만들려고 했다. 마이그레이션은 필요한 데이터를 모으고 재구성해서 다시 API를 호출해야 하는 과정인데, 이 과정을 비동기식으로 작성하려니 괜히 헷갈리고 코드 모양은 안나니 기분이 좀 상했다. 그 덕에 Promise 공부만 더 하게 됐다.

그래서 오랫만에 PHP로 작업했다. 두 서비스 모두 PHP SDK 를 지원하고 있어서 어렵지 않게 구현할 수 있었다.

Disqus 에서 작성자의 프로필 사진을 강제로 넣을 수가 없어 프로필 사진은 이전하지 못했지만 우선은 만족. Github 에 올렸다. FB2Disqus on Github

테스트가 없는 것과 FQL 을 쓰면 좀 더 나을 뻔 했는데, 뭐 그건 문제가 생기면 작성하기로 하고..

그나저나 댓글창도 바뀌었는데 댓글 하나 달아주지 않으시렵니까? 🙂

Facebook social comment export to Disqus

FB2Disqus on Github

SSI 를 활용한 프론트엔드 리소스 버저닝

개요

리소스 버저닝은 리소스 캐시를 목적으로 한다. 리소스 캐시는 해당 파일이 변경된 경우 컨텐츠를 새로 전송(Cache Miss)하고, 변경되지 않았다면 컨텐츠를 전송하지 않는(Cache Hit)다.

많이 사용되는 방법으로 버전이름을 쿼리스트링(Query String, GET 파라미터라고도 함)에 명시하는 방법이 있다.

버전이름을 쿼리스트링에 명시하는 방법은

<script src="vendors.js?v0.9.5"></script>
<script src="app.js?v0.9.5"></script>   

이와 같이 버전이름(v0.9.5)을 파라미터로 적어주고, 이후 버전이 올라가면 버전이름을 변경시켜주는 방법이다.

<script src="vendors.js?v0.9.6"></script>
<script src="app.js?v0.9.6"></script>

이 방법은 파일 이름을 변경하지는 않지만 파일의 내용이 변경될 때마다 주소를 변경시키므로 브라우저나 웹서버 간에 혹시 발생할 수 있는 캐시가 먹어 파일이 갱신되지 않는 문제를 방지할 수 있다.

일괄 버전 업데이트? 새로 업데이트된 파일만 버전 업데이트?

하지만 위 방식에도 맹점이 있다. 만약 0.9.6 업데이트가 app.js 에만 관련되어 있다면 vendors.js 는 굳이 새로 전송할 필요가 없는데도 다시 전송하게 되므로, 버전을 모두 변경하는 방식은 약간의 손해를 감수해야 한다.

현재 Baas.io 프로젝트에서는 1. 빌드 프로세스에 버전명을 명시하기 까다롭고, 2. 잘 변경되지 않는 라이브러리파일과 자주 변경되는 어플리케이션 파일을 구분하고 있어서 새로 업데이트된 파일만 버전을 올려주는 방법을 적용했다.

자동 버저닝

SSI 코드

<!--#config timefmt="%s" --> <!-- 시간을 읽는 방법을 Unix Timestamp 로 설정 -->
<link href="/css/styles.css?<!--#flastmod virtual="/css/styles.css" -->" rel="stylesheet" type="text/css" /> <!-- last modified 타임을 GET 파라미터로 넘김 -->
<script type="text/javascript" src="/js/vendor/vendors.min.js?<!--#flastmod virtual="/js/vendor/vendors.min.js" -->"></script>
<script type="text/javascript" src="/js/app/common.min.js?<!--#flastmod virtual="/js/app/common.min.js" -->"></script>

결과

<link href="/css/styles.css?1355283501" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="/js/vendor/vendors.min.js?1359420532"></script>
<script type="text/javascript" src="/js/app/common.min.js?1360469267"></script>

새로 업데이트된 파일의 버전을 올려주는 방법을 자동화하기 위해 파일의 각 마지막 변경시간(Last Modified Time) 을 Unix 타임스탬프형식으로 쿼리스트링으로 넘겨주도록 했다.

이렇게 구성하면 각 파일의 마지막 변경시간(서버에 탑재된 시간)이 이 파일의 버전이 되므로 선택적으로 버저닝이 가능하다. 그리고 마지막 변경시간을 SSI 를 통해 구하도록 되어 있어서 수동으로 버전을 올려줄 필요가 없다.

장점

  • 버저닝 최적화/자동화
    • 릴리즈 주기에 맞춰 버전을 일괄변경 한 것이 아니라 각 파일마다 버저닝했으므로 업데이트 되지않은 파일들은 이전 캐시를 그대로 사용할 수 있다.
  • 간단한 적용
    • 빌드 과정에 손을 쓰지 않고 SSI 코드를 삽입한 것이라 간단하게 적용할 수 있었다.

단점

  • HTTP Request당 오버헤드 증가
    • 파일의 마지막 변경시간을 구해야 하므로 Disk IO 발생이 늘어나게 된다.

P.S.

squid 등 일반적으로 많이 사용되는 프록시 서버에서는 쿼리스트링이 달려있는 리소스들은 캐시를 타지 않고 모두 새로 받아온다고 한다. 이런 이유로 쿼리스트링으로 버저닝하는 것보다 파일명 자체를 변경시키는 것이 더 낫다고 한다. Revving Filenames: don’t use querystring

브라우저 자동완성 기능의 미래

Form element 에 autocomplete 기능이 소개된 것은 1999년 Internet Explorer 5이 최초였다. 이후 각 브라우저 별로 산발적으로 지원하던 자동완성 기능은 HTML5에 이르러 표준화 되었다.

HTML5 스펙은 2012년 12월 17일 버전으로 기준으로 함.

이전 스펙에서 autocomplete attriute 는 “on” 또는 “off” 값만 가질 수 있었으나 최근의 스펙에서는 on, off 외에 공백으로 분리된 토큰들을 가질 수 있다. 이에 따르면 attribute 이 on, off 가 아니라면 아래와 같은 순서로 동작한다.

  1. 첫 8글자가 “section-” 으로 시작하는 경우 필드가 이름을 가진 그룹에 속함을 나타낼 수 있다. (선택사항)

예를들어, 양식에 두개의 배송주소가 있을 때 아래처럼 마크업 할 수 있다.

<fieldset>
 <legend>Ship the blue gift to...</legend>
 <p> <label> Address:     <input name=ba autocomplete="section-blue shipping street-address"> </label>
 <p> <label> City:        <input name=bc autocomplete="section-blue shipping region"> </label>
 <p> <label> Postal Code: <input name=bp autocomplete="section-blue shipping postal-code"> </label>
</fieldset>
<fieldset>
 <legend>Ship the red gift to...</legend>
 <p> <label> Address:     <input name=ra autocomplete="section-red shipping street-address"> </label>
 <p> <label> City:        <input name=rc autocomplete="section-red shipping region"> </label>
 <p> <label> Postal Code: <input name=rp autocomplete="section-red shipping country"> </label>
</fieldset>
  1. 어떤 토큰은 둘 중 하나일 수 있다. (선택사항)

    • shipping 은 이 필드가 배송 주소 또는 연락처 정보의 일부임을 나타냄
    • billing 은 이 필드가 청구 주소 또는 연락처 정보의 일부임을 나타냄
  2. 다음 두 옵션 중 하나

    • 어떤 토큰이 아래 autofill field string 중 하나:
      • “name”
      • “honorific-prefix”
      • “given-name”
      • “additional-name”
      • “family-name”
      • “honorific-suffix”
      • “nickname”
      • “organization-title”
      • “organization”
      • “street-address”
      • “address-line1”
      • “address-line2”
      • “address-line3”
      • “locality”
      • “region”
      • “country”
      • “postal-code”
      • “cc-name”
      • “cc-given-name”
      • “cc-additional-name”
      • “cc-family-name”
      • “cc-number”
      • “cc-exp”
      • “cc-exp-month”
      • “cc-exp-year”
      • “cc-csc”
      • “language”
      • “bday”
      • “bday-day”
      • “bday-month”
      • “bday-year”
      • “sex”
      • “url”
      • “photo”
  • 아래 순서대로
    1. 어떤 토큰이 아래 값들 중 하나 (선택사항)
      • home, work, mobile, fax, pager
    2. 어떤 토큰이 아래 autofill field 스트링 중 하나
      • tel, tel-country-code, tel-national, tel-area-code, tel-local, tel-local-prefix, tel-local-suffix, tel-extension, email, impp

즉, 이 스펙에 따르면 아래와 같은 경우의 수가 존재한다.

<input name="country" autocomplete="on">
<input name="country" autocomplete="off">
<input name="country" autocomplete="country">
<input name="country" autocomplete="shipping country">
<input name="country" autocomplete="section-a shipping country">
<input name="billing_home_tel" autocomplete="section-a billing home tel">

이런 상세한 분류를 통해 브라우저가 앞으로 더 강력한 자동완성기능을 갖게 될 것이다.

예를 들어 명세서 청구주소는 집이지만, 배송은 회사에서 받게 되는 경우가 있을 수 있다. 이런 경우 billing 에 집 주소, 집 연락처가 저장될 것이고 shipping 에는 회사 연락처 등이 저장되는 형태로 세분화가 가능해질 것이다.

참고

평범한 인터렉션, 비범한 인터렉션

여러분은 지금 어떤 자세로 이 페이지를 보고 있나요? 혹시 턱을 괴고 마우스에 손을 올리고 있지는 않은가요?
웹서핑을 할 때 많은 시간을 마우스와 함께 합니다. 하지만 가끔 양 손 모두가 키보드 위에 올라오는 때가 있죠. 바로 양식(Form)을 입력할 때 입니다.

양식을 채워서 로그인을 합니다.
메일을 쓰는 것도 양식을 채우는 일 입니다.
글을 보고 코멘트를 달아주는 것도 양식을 채움으로써 가능합니다.

즉 양식은 웹을 보는데서 그치는 것이 아니라 더 적극적인 소통을 가능하게 하는 매우 중요한 도구 입니다.

Hours 인터랙션 시리즈의 첫 꼭지는 바로 이 양식에 대한 것입니다.

좋은 인터랙션을 가진 양식 = 적절한 힌트를 주는 양식

힌트가 없는 입력창 (휑~) 힌트가 없는 입력창 (휑~)

웹페이지에 위 그림처럼 입력창(Input Element) 만 놓여있다면 무슨 내용을 입력해야 할지 알 수 없을 겁니다. 따라서 입력창은 적절한 힌트를 제공해야 합니다.

웹에서 양식에 힌트를 제공하는 기본요소는 Label 과 Placeholder 가 있습니다.

Label과 Placeholder

문구용품 중에서 라벨이 있죠? Label 은 바로 그 라벨을 생각하시면 됩니다.
Placeholder 는 언어학적으로 “문장 속에 필요한 요소이기는 하나 그 자체의 뜻은 없는 것” 이란 뜻이 있습니다.

HTML 표준 명세에서는 이 둘을 각각 이렇게 정의합니다.
“label 요소는 사용자 인터페이스에서 캡션을 나타냅니다.”
“placeholder 속성은 짧은 힌트(한 단어나 짧은 구)를 나타냅니다.”
“placeholder 속성을 label 을 대체하기 위해 사용할수는 없습니다.”

정의가 한 번에 와닿지 않으신다면 아래 그림을 살펴보세요.

이 것은 아이폰의 메일 계정 설정화면입니다. 여기서 Name, Email 등 까만글씨로 표현된 것이 Label이고 example@gmail.com 같이 회색 글씨로 표현된 것을 Placeholder 라고 합니다.

Label 은 각 입력 항목의 이름을 나타내고 있고, Placeholder 에는 입력할 값의 예라던지 꼭 입력해야 함 등의 부가 정보를 나타내고 있습니다.
형식 면에서도 Label 은 일반 명사를 사용하고 있지만, Placeholder 는 비교적 자유롭게 적혀있습니다.

두 가지 정보를 함께 사용하면서 어떤 정보를 어떻게 입력해야 하는지, 꼭 입력해야 하는 정보는 무엇인지 한 눈에 알 수 있게 했습니다. UI/UX 에 강점이 있는 애플 답게 Label과 Placeholder 를 적절하게 사용하고 있군요.

커서가 위치해도 어떤 값을 입력해야 할지 알 수 있도록

Label 요소를 입력창 안쪽으로 밀어넣는 것이 최근의 경향입니다. 아래의 로그인창들을 보세요.

네이버 로그인 팝업 – OSX

iCloud 로그인 영역

두 사이트 모두 Label 요소를 입력창 안에 넣어서 공간을 절약하고 시각적으로도 좋은 디자인을 만들어냈습니다. 아이폰 메일화면의 Placeholder 와 비슷한 모양을 하고 있긴 하지만, 아이디나 비밀번호 같은 것은 Label 이라고 할 수 있습니다.

한가지 중요한 차이는 네이버는 커서가 위치하면 아이디라는 글자가 사라지는 것이고, iCloud는 Apple ID 이라는 글자가 옅게 표시되면서 남아 있는 것입니다.

사실, 네이버의 로그인 창에서 첫번째 입력은 아이디라는 것을 쉽게 추정할 수 있으니 전혀 문제 될 것이 없습니다. 하지만 입력해야할 내용이 사번이었다면 단번에 추정하는 것은 어렵지 않을까요? 그래서 이런 방식의 UI는 커서가 위치하더라도 (내용을 채우지 않았다면) Label을 계속해서 보여주는 것이 더 좋습니다.

내 텍스트 커서(Caret)는 어디있을까?

텍스트 커서는 얇고 긴 모양입니다. 그래서 눈에서 놓치면 다시 찾아내기가 쉽지 않습니다. 따라서 내 커서가 어디에 위치하고 있는지 명확하게 보여주는 것이 좋습니다.

네이버 로그인영역 – Windows XP, IE8

KBStar.com 로그인영역

이번에는 네이버와 국민은행 사이트입니다. 네이버는 커서가 위치한 입력창의 테두리를 녹색으로 만들어 커서의 위치를 보여줍니다. 반면 국민은행은 커서의 위치를 나타내는 곳을 따로 표시하고 있지 않습니다. 대부분의 평범한 사이트는 이런 형태로 서비스되고 있습니다. 로그인은 입력창이 두 세 개 정도이지만 회원가입과 같이 입력창이 많은 경우는 사용자가 길을 잃는 확률이 높아지므로 커서의 위치를 표시하는 것이 좋습니다.

평범과 비범의 차이는 바로 디테일

양식의 목적은 사용자가 제작자의 의도를 쉽게 파악해 적절한 정보를 입력하게 하는 것입니다. 이 목적을 잘 달성하려면 좋은 인터랙션이 필요합니다. 그런 의미에서 양식에서의 좋은 인터랙션은 세상에 없는 거창한 것이 아니라 사용자에게 주는 조그만 힌트로 충분합니다. 하지만 평범과 비범의 차이는 바로 그 한 치의 디테일에서 나오는 것이 아닐까요?

관련글

이 글은 KTH 디자인실에서 발행하는 Hours 에 실린 글입니다.

Safari 6 Web Inspector 로 iOS6 Safari 디버그하기

차기 아이폰 출시일이 9월 12일로 예상되고 있습니다. 아울러 iOS6도 출시될 텐데요.
Front-end 개발자로써 이번 업그레이드가 매우 반갑습니다. 기존의 Weinre와 같은 3rd party 프로젝트에 의존하지 않는, built-in 개발자 도구 연동기능이 추가되기 때문입니다. 이 기능은 OSX Safari6 와 iOS6 간의 연동으로 이루어 집니다.

대략 어떻게 사용가능한지 빠르게 정리하겠습니다. 환경은 OSX Mountain Lion(10.8.1), Safari 6(8536.25), iOS6 Developer Preview 3 입니다.

준비물

  • Mac OSX Lion, or Mountain Lion (Safari 6는 Windows 용이 출시되지 않았습니다.)
  • Safari 6
  • iOS6 Device
  • iPhone USB Sync Cable

디버그 방법

  • 아이폰 케이블을 맥컴퓨터에 꽂기
  • iOS Device 에서 설정 – Safari – 고급 – 웹 속성 활성화하기
    iOS Device 에서 설정 - Safari - 고급 - 웹 속성 활성화하기
  • iOS Device 의 Safari 를 켜고 디버그 할 페이지에 접속하기
    iOS Device 의 Safari 를 켜고 디버그 할 페이지에 접속하기
  • Safari 6 의 개발자 메뉴에서 자신의 iOS Device 이름과 디버그할 웹페이지 타이틀이 보이나 확인하기
    Safari 6 의 개발자 메뉴에서 자신의 iOS Device 이름과 디버그할 웹페이지 타이틀이 보이나 확인하기
  • 이제 Web Inspector 사용가능!
    OSX Web Inspector 화면
    iOS 디버그 페이지 화면

주의할 점은 iOS Device 화면에 Safari 가 올라와있어야 Safari 6 의 개발자 메뉴에서 디버그할 웹페이지를 고를 수 있습니다. 여러 페이지가 켜져 있는 경우에는 골라서 디버그 할 수 있으니 참고하세요.

이번 업데이트로 OSX-iOS에서는 Weinre 같은 네트워크를 통한 리모트 디버깅 환경을 사용하지 않아도 됩니다. 그리고 케이블로 연결해 디버그 하므로 성능면에서 월등합니다. 하지만 Windows 에서 지원하지 않는 점은 아쉬운 점으로 남겠네요.