이글로써 RSS에 대한 논쟁은 그만~ 이라고 말하고 싶긴 하지만, 그럴 깜냥은 아니고.
블로그 개발자들에게 도움이 되었으면 하는 마음에 적는다.
모두에게 happy한 RSS만들기, 그것은 기본에 충실하면 아주 간단한 일이다.
샘플 코드는 여기에.
주욱 따라오자. 중요한 곳은 행번호를 굵게 써둔다.
1행은 따로 설명할 필요 없고… 아, UTF-8로 만들어야 함을 잊지 말자.
2행 : rss버전과 그외 xml에서 사용되는 namespace에 대해 미리 선언을 해둔다. 이 예에서는 content라는 확장 namespace를 사용함을 알리고 있다.
4행 : title은 필수 요소이며, 채널 제목을 가리킨다. 채널의 title은 기왕이면 웹사이트의 이름과 동일하면 좋으나, 하나의 사이트가 여러개의 RSS채널을 가질 수 있으므로(예:코멘트RSS, 검색결과 RSS) 다른 채널과 구분짓도록 이름을 쓰자. encoding되지 않은 plain text를 사용해야한다. (이하 특별한 언급이 없다면 text가 들어가는 모든 부분에 동일).
5행 : link는 이 RSS 채널이 언급하는 사이트의 주소를 가리킨다. 역시 필수.
6행 : description은 이 RSS채널에 대한 설명을 간단히 적어넣는다. 역시 필수.
7행 : language는 ko-kr (한국이니까. 이 역시 사이트의 기본 language와 동일하게 맞춰준다.). 여기서부터는 써도 좋고, 안써도 좋은 선택사항.
8행 : copyright는 가입형 블로그라면 골치아플 수도 있다. 저작권이 어디에 있는가를 명백히 표시해주는 것이 좋다. 물론 블로그의 정책에 따라서.
9행 : pubdate는 발행시간. RFC822기준이다. 가끔 이 pubdate형식을 틀리는 경우들이 있으니 주의. 특히 외국산 설치형블로그들을 한글화하면서 날짜형식을 바꿨을 때에는 간혹 이 RSS에도 반영이 되어 문제가 생길 수 있다. GMT대신 +0900 처럼 적어도 된다.
10행 : lastbuilddate와 pubdate를 헷갈릴 수 있는데, 이는 최종적으로 수정된 시간을 가리킨다. 이것과 pubdate를 이용해서 RSS 리더들이 문서 갱신여부를 확인한다. 따라서 “나중에 글을 수정했는데 반영이 안되는 문제…”를 고민하는 거라면 자신의 RSS 파일이 이 정보들을 제대로 가지고 있는지 확인해보라. 그리고는 RSS리더기 제작자에게 이 정보들을 이용해 수정사항이 반영되도록 압력을 가하라. 즉, “나중에 글을 수정했는데 반영이 안되는 문제”를 해결하고 싶다면, 첫째, 자신의 블로그 제작자에게 pubdate와 lastbuilddate 정보를 정확히 제공하도록 요구하고, 둘째로 RSS리더기 제작자들에게 pubdate와 lastbuilddate를 반영하도록 요구해야 한다는 뜻이다. (이걸 가지고 엄하게 사용자끼리 전체공개를 해야 하네 말아야 하네 하는 것은 해프닝일 뿐이다.)
11행 : docs는 RSS파일 포맷형식이 기술된 곳을 가리킨다. HTML의 DTD라고 생각해도 좋다. 몇십년이 지나서 누군가 이 RSS파일을 열어보더라도 참조할 수 있는 사전을 알려준다는 뜻이다. RSS 2.0이라면 http://blogs.law.harvard.edu/tech/rss 를 적어주면 되긴 하는데, 한가지 문제가 있다. content:encoded같은 확장 RSS 2.0을 쓴다면 그 내용이 기술되어 있는 곳을 적어주라는 점.
그러나 이 항목은 대개 생략해도 큰 문제는 없는데, 대부분의 RSS리더들은 이 항목을 실제로 사용하고 있지는 않기 때문이다. Feed Validator들이나 사용할까… 따라서 크게 신경쓸 필요는 없다. 게다가 3행에서 이미 xml namespace에 대해 기술했기 때문에 없어도 되는 항목.
12행 : generator는 이 RSS를 만든 프로그램을 가리킨다.
13행 : managingeditor는 컨텐트 편집자의 이메일 주소를 가리킨다. 만약 사람 이름을 병기하고 싶다면, “xxx@blog.ooo.com (개똥이)” 처럼 ()안에 병기하면 된다. 단 이름만 적으면 안된다. 여기에도 한가지 문제가 있는데, RSS에 적혀있는 이메일 주소는 스패머들에게 좋은 먹이감이 되기 쉽상이라는 점이다. 그러나 그럼에도 불구하고, 아예 이 항목을 안쓴다면 모를까, 쓴다면 메일주소는 적어주도록 하자. 필요하다면 nospam형식으로 변형시키는 것도 가능하겠다.
14행 : webmaster는 이 사이트 전체의 웹마스터이다. 역시 이메일 주소를 적는다.
15행 : category별 RSS제공을 안하는 경우들이 많은데, 해주면 감사할 이들이 참 많을 것이다. 만약 category archive같은 것이 있다면 domain 속성을 이용해 해당 URL을 기술해주면 더 좋다.
16행 : cloud는 거의 쓰이지 않을 항목일 것이다. 원래는 RSSCloud라는 웹서비스를 지원하기 위한 항목이다. 물론 예시에 든 것처럼, rpc.allblog.net 같은 건 실제로 없다. 만약 올블로그가 rpc서비스를 만든다면 이런 식으로 쓰면 된다.. 는 뜻이다. RSSCloud에 대해 좀 더 자세히 알고 싶다면 여기 참조.
17행 : ttl은 time to live의 약자이다. 이 RSS 파일이 생성된 후 몇 분간 “유효”한가를 알려주는데 사용된다. 어떤 RSS파일은 발행된지 너무 오래되어 그 내용이 사이트와 맞지 않을 수도 있다. 이럴 때를 대비해서 사용한다.
18~23행 : textInput은 구독자와의 interactive action을 위해 준비된 항목이다. 용도는 위에 적은 예외에도, 품질평가라든가, 구독확인이라든가… 뭐 이래저래 다양한 곳에 쓰일 수 있다… 고는 하는데, 실제로 지원하는 RSS리더기가 거의 없어서 유명무실하긴 하다. RSS 리더기를 만들 개발자라면 한번 구현해보시길.
24행 : rating은 PICS rating을 지정하는데 쓰인다. PICS rating은 해당 아이템에 대한 PICS등급을 매기는데, 원래는 아이들에게 접근가능한 컨텐트인지 확인하는데 쓰였으나 현재는 그밖에도 여러 용도로 쓰인다.
허나 국내에서는 PICS를 활용하는 서비스도 없고 해서 굳이 적어둘 필요는 없는 항목이다. 만약 해외에 교육용으로 쓰일 사이트라면 알아두는 것도 좋겠다.
25~29행 : image는 이 RSS 채널을 상징하는 이미지 배너를 정의하는데 쓰인다. 필수는 아니나 지정해두면 몇몇 RSS 리더기에서는 괜찮은 외관을 보이는데 쓰인다. GIF, JPG, PNG 모두 가능하며, 사이즈는 최대 144X400 이지만 88X31이 기본값이다.
30~37행 : skiphours와 skipdays는 RSS 리더기의 수집을 금하는 시간을 지정한다. 위의 예에서는 매일 0시부터 3시까지의 수집을 금하며, 덧붙여 일요일에는 수집을 금한다는 뜻이다. 수집을 금하는 이유는 여러가지가 있는데, 이른바 사이트 정기점검 등의 문제가 있기 때문이다. RSS를 수집하러 갔는데 해당 파일에 접근할 수 없다면 수집기는 이 사이트가 더이상 존재하지 않아서라고 판단할 수도 있다. 이런 것을 방지하기 위해 수집기의 활동을 금지하는 시간을 RSS채널에 적어둔다. 물론 이 항목들은 이외에도 트래픽관리등을 위해서도 쓰인다.
사실, 이 skiphours, skipdays 그리고 ttl 항목을 통해 수집기들이 내 RSS를 긁어가는 시간을 조절할 수 있어야 하는데, 국내의 많은 리더기들은 이 항목들을 반영하지 않는다. 무조건 10분에 한번씩 RSS를 읽어가는 모 메타블로그같은 경우, 이미지도 매번 긁어가기에 트래픽량이 장난이 아니다. ttl에서 60분간 유효하다 했으면 60분마다 긁어갈 것이지… 요즘은 수정되었는지 모르겠다.
39행부터는 개별 항목(item)에 관한 내용이다.
40행 : title은 필수요소이며 해당 아이템에 대한 제목이다. 블로그 글목록 RSS라면 엔트리제목일테고, 신상품RSS라면 상품제목일테고…
41행 : link는 해당 item의 “원본”을 가리키는 URL이다. 주지하다시피, RSS란 원본에 대한 또다른 카피가 아닌, “원본에 대한 설명”임을 명심하자.
42행 : description은 해당 item에 대한 설명이다. 만약 description이 item 그 자체라면 title과 link는 생략가능하다. 최소한 title과 description 둘 중에 하나는 반드시 있어야 한다.
description은 인코딩되지 않은 plain text이며 다음과 같이 CDATA나 entity encoding을 사용할 수 있다.
[xml]
[/xml]
[xml]
[/xml]
description은 말 그대로 해당 item에 대한 설명이다. 조금 철학적인 문제로 들어가서, 그럼 과연 “해당 item에 대한 설명”이란 무엇인가? 가장 좋은 것은 요약(excerpt)이다. 신문의 헤드라인을 생각해도 좋다. 문제는 국내의 대부분의 블로그툴에 excerpt를 입력받는 방법이 없다는 것이다. 왜 안넣는지는 모르겠다. 분명 사용자들이 excerpt를 제대로 입력할 것이라는 기대는 어렵다. 100명중에 1명이나 제대로 입력할까.
사실, 요즘 유행하는 more 기능이라는 것도 원래는 excerpt - entry body 개념에서 나온 것이다. index archive에서는 excerpt만 보여주고 해당 페이지에 들어가야 entry body를 보여주는 방식이었는데(물론 선택가능하다.), 이것이 우리나라에서는 어찌어찌 와전되어 그저 본문을 접었다 폈다 하는 기능으로 바뀌었다. 귤이 회수를 건넜더니 탱자가 되더라. 아니 한라봉이 된걸까?
어쨌거나 바라노니, 국내의 블로그 제작자들은 블로그에 글 쓸 때 excerpt를 입력받는 기능을 추가해주었으면 좋겠다. excerpt는 여러가지로 쓰일 수 있는데, RSS뿐만 아니라 index페이지나 archive페이지에서 글의 개요를 보여줄 때도 쓸 수 있고, 또 more 기능을 구현할 때에도 쓰일 수 있다.
만약 사용자가 excerpt를 입력하지 않는다면??? 그럴 경우 de facto표준인 MovableType에서는 사용자가 입력한 글 중 일부를 따와서 excerpt 대신 사용한다. 물론 MT의 경우에는 몇자나 딸지 지정가능하고, 그 지정에 따라서 본문 전체를 description에 담을 수도 있다. 나름 합리적아닌가?
description안에 html 태그를 넣는 것은 지양해야 하는데, 그 이유는 모든 리더기가 description의 html을 해석하지는 못하기 때문이다. 즉, 이 안에 html 태그를 적는다 해서 그대로 보여준다는 보장은 없다. 그 외에도 여러가지 문제가 있긴 하다.
43행 : author는 글쓴이의 email주소를 가리킨다. 싱글유저-싱글블로그인 경우에는 channel의 managingeditor와 대개 동일하므로 생략해도 좋긴 하지만, 되도록이면 적어주는 것이 좋다.
44행 : category는 말 그대로 해당 글에 대한 카테고리. 멀티 카테고리나 요즘 유행하는 Tag등을 표시하는 데 사용하면 좋다. 사실 이 category를 국내 블로그도구들이 제대로 지원하지 않는 바람에, tag구현에 link rel=”tag” 같은 방식이 쓰이는 실정이다.
45행 : comments는 만약 커멘트 등을 달 수 있다면 그 위치에 해당하는 URL을 기술해준다. 왜 이것이 별도의 URL로 기술해주는가 하면, 몇몇 CMS 시스템에서는 글과는 별개로 커멘트 다는 곳이 따로 있기 때문이다. 몇몇 Article-Forum 시스템이라든가, Blogger.com 같은 곳이 그렇다. 여기에 커멘트 입력 페이지 URL을 적어주면 RSS리더기에서 바로 커멘트 입력 페이지로 이동할 수 있게 되어 사용자 편의를 높여준다. 국내의 대부분의 가입형 블로그들도 커멘트 표시에 iframe을 이용하느니만큼 여기에 커멘트 페이지 url을 적어주면 감사하겠다.
46행 : pubdate는 이 아이템이 작성된 시간을 가리킨다. 만약 이 것이 현재 시각보다 미래라면 RSS 리더기는 사용자에게 이 아이템을 보여주면 안된다. 블코나 올블 같은 경우에 옛날에는 이 부분이 개선되지 않아서 pubdate조작으로 늘 상위에 올려지는 경우가 있었는데 요즘에는 안그런 걸로 알고 있다.
47행 : guid는 이 아이템에 대한 고유한 값을 나타낸다. 형식은 아무래도 좋지만 대개 permalink를 사용한다. 이 guid는 필수는 아니긴하지만, 리더기가 수집된 RSS를 관리할 때 키값으로 사용해야 하므로 우주를 통틀어(?) 고유한 값이어야 한다. 같은 제목에 같은 url이지만 내용이 바뀌게 되었고 그것을 알리고 싶다면 guid값을 변경함으로써 새로운 item임을 RSS리더기에 알리게 된다. 즉, guid가 다르면 리더기는 “새글”이라고 판단하게 된다. 반대로, guid값이 같다면 제목을 바꾸거나 내용이 바뀌고, 심지어 url이 바뀌어도 RSS 리더기는 “새글이 아니라고” 판단하게 된다. 이쯤되면 식상한 이야기겠지만, 국내의 RSS리더기들은 이것을 제대로 지원하는 경우가 드믈다.
만약 guid에 permalink를 사용한다면
[xml]
[/xml]
처럼 써주는 것도 좋겠다. 실은 ispermalink는 기본값이 true이긴 하다.(permalink에 대해 좀더 자세히 알고 싶다면 일단은 여기 참조)
48행~49행 : enclosure는 꽤 중요한 항목인데 이 역시 은근 무시되고 넘어가기 일쑤인 항목이다.
결론부터 말하자면, 미디어 첨부파일이 있다면 description이나 content:encoded에 embed로 넣지 말고 enclosure에 URL을 적어줄 것.
그럼 왜 본문중에 embed로 걸어두면 될 걸 뭐하러 여기에다 적는지 궁금할 것이다.
데스크탑용 리더기의 경우, enclosure에 적어둔 링크는 사용자의 PC에 저장된다. 리더기는 적당히 알아서 해당 미디어파일을 천천히 다운받아 저장해두고, 사용자가 해당 아이템을 읽을 때마다 저장된 파일을 불러서 플레이해준다. 그럼으로써 얻는 이득은 1) 트래픽속도에 상관없이 내 PC에서 실행시키므로 실행이 빠르며, 2) RSS제공자의 트래픽을 절감시켜주는 효과가 있다.
회선속도가 안좋은 PC에서 RSS 본문에 임베딩된 미디어 파일들은 리소스와 트래픽을 잡아먹는 원흉들이다. 모두가 XPEED로 날아다니는 것은 아니다. 심지어 사양이 안좋은 PC에서는 RSS를 읽어들이다가 본문에 걸린 미디어파일들 때문에 뻗어버리는 일도 있다.
웹리더기의 경우에는 이렇게 미리 다운받아 놓을 수는 없지만, 최소한 본문중에 직접 임베딩을 뺌으로써 트래픽과 CPU 리소스를 절감할 수 있다. 필요한 경우에만 enclosure에 언급된 링크를 클릭함으로써 플레이하거나 다운받을 수 있게 된다.
개인적으로는, content:encoded를 꺼려하는 제일 큰 이유는 본문중에 이놈의 임베디드 미디어파일들이 트래픽과 리소스를 잡아먹는 것이 꼴보기 싫기 때문이다. 마치 홈페이지에 들어가면 배경음악이 자동으로 실행되는 것만큼이나 불편하고 예의없는 일이다.
50행 ~ 52행: content:encoded… 말많고 탈많은 그분 차례다. 일단 2행에서 namespace선언을 했음을 상기하자. 즉, content:encoded는 필수가 아닌 선택사항이라는 뜻이다. HTML 태그가 포함된 본문을 적고 싶다면 이 안에 적자. 물론 CDATA와 HTML entity인코딩은 필수.
그럼에도 불구하고, 리더기마다 보여주는 방식은 다를 수 있기 때문에 table이나 script 같이 문제될 만한 tag들은 빼고 발행하는 것이 예의. 물론 플래쉬나 임베딩된 미디어파일들도 빼고 enclosure를 활용해주는 것이 옳다. 똑똑한 리더기들은 알아서 해결해주기도 하지만 모든 리더기가 그런 것은 아니니 주의.
content:encoded는 기본은 아니지만 많은 리더기에서 지원하고 있다. 물론 content:encoded를 쓰는 것을 환영하는 사람들도 많고 확실히 편리하다. 이처럼 RSS 2.0 기본 스펙은 아니지만 유용하게 쓰이는 확장 namespace들이 있다. 대표적인 것 몇가지만 소개를 해보면…
wfw - Well-Formed Web CommentAPI
well-formed web을 구현하기 위해 확장된 XML namespace이다.
wfw:comment - RSS 2.0의 comments 항목을 대신한다. 큰 차이는 없다.
wfw:commentRSS - 해당 item의 comment목록에 대한 RSS 링크를 기술한다. “이글에 달린 댓글 RSS”쯤 되겠다.
dc - Dublin Core Metadata
더블린 코어는 문서등의 메타데이터를 기술하기 위한 XML namespace이다. 자세한 내용은 링크를 참조하고…
주목해야 할 부분은 다음 항목이다.
dc:creator - RSS 2.0의 author, managingeditor, webmaster등의 항목이 이메일 주소를 필수로 하기 때문에 스패머의 좋은 먹이감이 될 수도 있다. author대신 dc:creator를 사용하면 이메일 주소를 적지 않고 이름만 적어도 된다. 이메일 주소 보호에 자신이 없다면 dc를 사용하는 것도 좋은 방법이다. (전에 모 블로그 개발 게시판을 보다보니 이메일 주소 수집이 겁나서 author항목을 일부러 틀린채로 내버려둔다는 글귀를 보았기 때문에 적어둔다.)
trackback RDF
트랙백 주소를 구하는 것은 파서제작자들에게는 매우 골치아픈 일이다. 본문과 RSS에 trackback RDF를 적어주면 모두모두가 행복할 텐데…
trackback:ping - 이 글의 트랙백 주소. (아이템당 1번만 사용)
trackback:about - 이 글에 걸린 트랙백들의 주소.
Trackback RDF를 HTML본문과 RSS에 사용하게 되면 개발자들이 Trackback Auto-discovery 기능을 만들거나, 북마클릿을 만들 때 유용하게 쓰인다. 부디 꼭 적어주시길. (국내에서는 egloos와 enbee를 제외하고는 trackback RDF를 지원하는 블로그 도구가 없는 듯 하다. 물론 Trackback Auto-discovery등을 지원하는 것은 당연히 없고.)
iTunes
iTune을 이용한 Podcasting등을 위해 만들어진 namespace.
media RSS (Yahoo)
media RSS를 작성해두면 Yahoo에서 검색시 깔끔하게 인덱싱 해준다. 뭐, 국내에서는 별 필요없겠지만.
creativeCommons
CC딱지를 붙여 놨다고 저작권이 자동으로 지켜지거나 하는 것이 아니다. 이 CC RDF를 웹페이지와 RSS안에 심어둬야만 기계들이 파악할 수 있다. CC 딱지를 붙일 수 있는 국내 블로그툴들이 몇개 있는데, 왜 CC RDF는 안붙여줄까. 어이없는일.
기타 여러가지 확장 namespace들에 대해서는 여기 참조. (다 쓰려니 귀찮…)
대충 이정도면 블로그 개발자나 RSS 리더기 개발자들이 알아둬야 할 것들은 대충 정리한 듯 싶다. 부디 편리하고 깔끔하게 블로깅을 할 수 있도록 스마트하게 개발 좀 해주시길.