13 Apr 2008
1. 문제 발생
워드프레스는 주소 체계를 이용자가 원하는 다양한 형태로 꾸릴 수 있는 기능을 제공한다. 이용자가 글 마다 주소를 만들어서 지정하거나 날짜, 혹은 글 번호 등 다양한 변수를 써서 주소를 꾸릴 수 있다. 한날의 낙서와 한날은 생각한다는 주소 체계를 /%postname%/ 라고 설정하고 글 마다 주소를 정하고 있다. (솔직히 아주 귀찮다. -_-)
이렇게 자유로운 주소 체계 가능하다보니 사람들이 워드프레스 주소 체계를 정확히 이해하지 않은 상태에서 주소를 만들어 쓰다가 낭패를 겪는 경우가 있다. 예를 들면, 글 주소 체계를 숫자로만 한 경우이다. 이 주소 체계는 글 숫자가 1000 미만인 경우 문제가 없지만 1000 이상이면 문제가 생긴다. 예를 들어보자.
“이 글은 존재하는 글이지만 접근할 수 없는 글입니다.”라는 글의 낱장 주소는 http://blog.hannal.com/1023 이다. 그런데 이 글의 낱장 주소인 http://blog.hannal.com/1023로 접근하면 그런 글이 없다고 나온다. 이 글 미리보기 기능 주소인 http://blog.hannal.com/?p=1153&preview=true 로 접근해야 글을 볼 수 있다. 왜 이런 일이 생기는 것일까? 워드프레스의 오류(버그)일까?
2. 문제 원인
결론부터 말하자면 오류가 아니다. 나 조차 워드프레스 구조와 흐름을 꼼꼼히 살펴보지 않았을 때에는 워드프레스 오류라고 생각했었다. 이 문제는 사실 워드프레스 주소 체계와 기계의 고지식함(?)을 생각하면 아주 당연한 것이며, 따지고보면 이용자 부주의로 생긴 일이다.
워드프레스 주소 종류는 다음과 같이 나뉜다.
- 쪽 글(page) 주소 : /기본주소/쪽주소/
- 관리자 영역 주소 : /기본주소/wp-admin/
- 년도/달 단위 주소 : /기본주소/년도/달/
- 글 갈래 주소 : /기본주소/category/ (혹은 따로 지정 가능)
- 꼬리표 주소 : /기본주소/tag/ (혹은 따로 지정 가능)
이외 몇 가지 규칙이 더 나올 수 있는데 여기선 논외로 치자. 여기서 중요한 것은 바로 세 번째 항목인 “년도/달 단위 주소”이다. 만약 워드프레스를 “도메인/blog/”에 설치했을 경우 년도/달 단위 주소는 “도메인/blog/2008/04” 형태가 된다. 바로 이것이 문제(?)이다. 만약 글 주소 체계를 글 번호로만 하거나 혹은 글 주소 이름으로만 한 뒤 그 주소 이름을 1000 이상 숫자로 하는 경우, 그러니까 “도메인/blog/1000” 이런 식으로 할 경우 “년도/달 단위 주소”와 주소 규칙이 부딪히게 된다.
워드프레스는 기본주소 바로 뒤에 붙는 숫자가 1000 이상인 경우 이 숫자를 년도로 인식한다. 그러므로 글 주소가 워드프레스를 설치한 기본 주소 바로 뒤에 숫자 1000 이상인 경우 글로 접근하질 않고 1000년으로 접근을 한다. 당연히 1000년에 쓴 글이 없을테니 자료가 없다고 나오는 것이다.
3. 문제 해결
해결 방법은 간단하다. 글 주소를 기본 주소 바로 뒤에 숫자로만 붙게 하지 않으면 된다. 아니, 붙게 하더라도 그 숫자가 1000이상이 되지 않게 하면 된다. 혹은, 이 숫자 앞이나 뒤에 다른 문자열을 넣어서 년도와 구분을 해주면 된다.
해결 예제
- /%post_id%/ => /archives/%post_id%/ , /entry/%post_id%/ , /a/%post_id%/ , 이외 글 주소와 년도/달 단위 주소를 구분 지을 문자열이면 아무거나 무관. (숫자 빼고 -_-; )
- 혹은 아예 다른 주소 체계
굉장히 좋은 방법은 글 주소 구조에 해당 주소가 글 주소라는 걸 알 수 있는 낱말을 집어 넣는 것이다. /entry 라든가 /archives 같은 걸 넣는 것이다. 그렇게 하지 않고 나처럼 /%postname%/ 이렇게 하면 글 주소 이름을 숫자로 하지도 못하고, 그렇다고 글 주소를 한글로 하기도 애매해서 매번 글 주소 이름을 영문으로 짓느라 고생하게 될 것이다. -_-; 워드프레스 2.5에 주소체계 견본으로 /archives/%post_id%/ 가 괜히 있는 것이 아니다.
(굳이 변명을 하자면 난 워드프레스 1.2때부터 썼는데 당시엔 이런 배려가 없었으며, 예쁜주소(fancy url) 기능을 만들어주는 .htaccess 관리 정책도 지금과 완전히 달랐다)
덧쓰기 : 윽, 젠장. 이 글 주소에 wordpress를 오타 쳐서 wordpres 라고 쳤다. -_-
11 Apr 2008
1. 들어가며
며칠 전에 구글에서 Google App Engine이라는 플랫폼을 공개했다. 소식을 접하자 마자 계정 신청을 했는데 오늘 계정이 활성화 됐다는 전자우편이 왔다. Google App Engine에 대해 보다 자세한 우리말 글을 보고 싶다면 likejazz님께서 쓰신 구글 웹 어플리케이션 플랫폼: App Engine 글을 참조 바란다.
2. 가볍게 둘러 본 느낌
난 방금 전에 Google App Engine (이하 GAE)에 예제를 따라 Hello world성 문장을 만들어 뿌려봤다. 마침 Django도 지원하길래 django를 이용해서 비슷한 일을 해봤다.
이리 저리 둘러 보고
- 이거 정말 짱이다
- GAE를 기반으로 하는 서비스가 많아지면 MS passport 서비스가 실패했던 것과는 달리 Google account(gmail)은 성공할 수 밖에 없다. Open ID보다 더 Open ID스러운 놈이 될 수도 있을 것이다
- 기획자나 작은 서비스 기업, 혹은 개발자(엔지니어 말고)들은 정말 신나겠다
- 역시 구글은 무섭다. GAE는 서비스 개발계의 Google Adsense가 될 것이다
이와 같은 느낌을 아주 강렬하게 받았다.
3. 좋은 점
요즘 개발 인트라넷으로 각광 받고 있는 도구는 Trac과 Subversion이라고 생각한다. 자료 판숫자(version)나 Wiki를 통한 문서 관리가 편하기 때문이다. 무엇보다 협업을 편리하고 안전하게 할 수 있다는 점이 아주 좋다. GAE 역시 이런 점이 잘 되어 있는 걸로 보인다. 잘 되어 있다고 확실하게 말을 하지 못하는 이유는 그런 기능이 보이기는 하지만 아직 제대로 실험을 하지 않았기 때문이고, svn 같은 것도 여전히 따로 필요해 보이기 때문이다.
하지만 소스를 갱신할 때마다 소스 판숫자를 자동으로 올릴 수 있다.
어렵고 골치 아픈 부분은 신경 쓰지 않고 서비스 개발 자체에 집중할 수 있는 환경도 좋은 점이다. 서비스가 잘 되어 확장을 해야 할 때, 개발 초기에 확장성을 고려하지 않으면 큰 고생을 한다. 그래서 개발 초기에 설계에 많은 시간을 들인다. GAE를 쓰면 이런 부분을 신경 쓸 일은 없을 듯 싶다. 서비스 확장을 할 때 Database Server와 Application Server를 주로 확장할텐데 이 두 부분을 GAE가 맡기 때문이다. 서버 뒷단에서 어떻게 분산을 하는지 신경 쓸 것 없이 나는 API로 자료를 꺼내 쓰거나 넣으면 된다.
아직 이용자가 많지 않아서 그런지는 몰라도 GAE 서비스 자체가 빠른 점도 좋다. 값싼 어지간한 웹호스팅 보다 훨씬 낫다. -_-;
SDK도 잘 만들어져 있다. Rails 나 Django가 그러하듯이 GAE SDK도 내장 웹서버가 있어서 GAE에 계정이 없더라도 개발 자체는 진행해 나갈 수 있다. 그리고 이 SDK 기반에서 잘 작동하면 GAE 위에서도 잘 돌아갈 확률이 높은 편이다. 왜 “높은 편”이라는 다소 불확실한 말을 썼냐하면, 아직 SDK 완성도가 완전치 않아서 개발 환경(내장 웹서버)에서 잘 작동하는 것이 GAE 안에서는 오류가 나는 경우가 있고, GAE에 소스 코드를 올릴 때 GAE가 소스 파일 일부 내용을 고치는지 개발 환경에서 뜨는 화면과 GAE 위에서 뜨는 화면이 달라지는 경우가 있는 듯 싶다. 대체로 python 경로(path)와 관련된 부분에서 그러한데, GAE에서 제공하는 문서를 보면 어렵지 않게 문제를 피할 수 있다.
이용자 인증 체계도 아주 쉽게 처리할 수 있다. The Users API 문서를 보면 알겠지만, Google account(Gmail)과 이용자 정보 기능을 연결해놨다. Google App Engine 을 기반으로 하는 서비스가 많아지면 많아질수록 gmail 계정 하나로 편리하게 서비스에 접근하여 쓸 수 있게 될 것이다. 이거 어디서 보던 개념 아닌가? 그렇다. 바로 Open ID이다. Open ID는 인증 체계만 덜렁 제공한다면, GAE는 인증 체계와 더불어 Application을 편하게 만드는 환경까지 제공하는 것이다. 정말 기가 막히고 무섭다.
마지막으로 나한테 좋은 점은 (현재) 쓸 수 있는 개발 언어가 python인 점이다. 난 python을 좋아하기 때문이다. :)
4. GAE 안쪽 살펴보기

우선 처음 가면 Application을 만들라고 나온다. 현재는 이용자당 3개를 만들 수 있으며 한 번 만든 Application은 지우거나 ID를 고칠 수 없다.

Dashboard에는 각 Application(Service) 관련 로그들이 나온다. 서비스 감시 및 현황을 파악할 때 좋을 것이다.
내가 마음에 들어했던 부분은 바로 로그 보기 기능이다. 총 7가지에 로그를 볼 수 있다.
- debug log line
- An info log line
- A warning log line
- An error log line
- A critical log line (most severe)

크흑. 정말 기가 막히지 않은가!

Google Account를 가진 이용자에 한해서 개발에 참여시킬 수 있다. Google apps를 통해 계정을 만든 이용자도 참여가 가능하긴 한데 몇 가지 문제가 있어서 깔끔하게 되지 않는다. gmail.com 계정을 초대하고 참여하는 것이 명랑한 삶을 사는 데 도움이 될 것 같다.
당연히 있을 법한 기능 중 하나는 GAE에 올린 서비스에 도메인을 따로 붙일 수 있는 것이다. 이 기능은 Google apps를 통해야 한다.

Google Apps 관리자 화면에 가면 아마 GAE 관련 서비스 추가 항목이 없을 것이다. 그럴 경우 위 그림과 같이 도메인 설정 영역 중 제어판에서 “다음 세대”라는 항목을 적용해야 한다. 그러면

이와 같은 도메인 연결란이 생긴다. 예를 들면 http://hello-hannal.appspot.com에 http://helloworld.hannal.com을 연결한 것이다.
5. 실제로 Hello world 찍어보기
여기서는 GAE에 hello world를 출력하는 과정을 보이는 것이 목적이지 python이나 django 강의를 하는 건 아니다.
5-1. 어플리케이션 생성
우선 GAE SDK 디렉토리 안에 GAE에 추가한 Application 디렉토리(폴더)를 하나 만든다. GAE에 만든 Application ID와 꼭 같을 필요는 없다. 근데 여기서는 Django를 이용할 것이므로 django-admin.py 을 이용해 만들기로 하자.
django-admin.py startproject uw
그러면 uw라는 디렉토리가 생기고 django 관련 기본 파일들이 만들어져 있다. 왜 helloworld가 아니라 uw인가하면 별 뜻 없다. hello world가 지겨워서 unlimited world라고 하고 싶었기 때문이다.
이제 app.yaml 파일을 uw 디렉토리 안에 만들고 다음 내용을 써넣는다.
application: uw
version: 1
runtime: python
api_version: 1
handlers:
- url: /.*
script: main.py
YAML 설정에 대한 자세한 내용은 Configuring an App 문서를 참조 바란다.
보면 / 로 들어오는 모든 요청을 main.py 이 받게 했다. 이 main.py는 Running Django on Google App Engine 문서에 설명이 잘 나와있다. 다만 이 문서대로 하면 settings.py 에서 오류가 발생하는데 settings.py 맨 위에 import os 를 써넣으면 된다. 템플릿 경로 지정 문제 때문에 그런 것이다.
5-2. 화면 만들기
이번엔 / 로 들어왔을 때 보일 화면을 만들자. 간단하다. 우선 urls.py 에 접근 요청 경로와 이 경로에 연결할 함수를 정의한다.
urlpatterns = patterns('',
(r'^$', 'views.root_page'),
(r'^hannal/$', 'views.goto_hannal'),
)
난 아무 경로 없이 최상위 경로(/)로 왔을 때 views.root_page 를, /hannal로 왔을 때 views.goto_hannal을 실행하겠다고 했다.
이번엔 views.root_page 를 만들 차례이다. 취향에 따라 views.py 안에 각 함수를 만들어도 되고 views 디렉토리 안에 root_page.py 나 goto_hannal.py 파일을 만들어도 되지만, 난 views.py 안에 각 함수를 만들기로 했다.
urls.py 나 settings.py 파일이 있는 곳에 views.py 를 만든 뒤 다음과 같이 내용을 만든다.
# -*- coding:utf-8 -*-
from django.http import HttpResponse, HttpResponseRedirect
import django
def root_page(request):
str = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">'
str += '<html>'
str += '<head><title></title><meta http-equiv="content-type" content="text/html; charset=utf-8"/></head>'
str += '<body>'
str += '<p>안녕하세요, 여러분. 이 화면은 '
str += '<a href="http://www.djangoproject.com">Django %s.%s</a>로 만들었고, ' % (django.VERSION[0],django.VERSION[1])
str += '<a href="http://appengine.google.com">Google App Engine</a>에서 '
str += '돌리고 있답니다.</p>'
str += '</body></html>'
return HttpResponse(str, mimetype='text/html')
def goto_hannal(request):
return HttpResponseRedirect('http://www.hannal.net')
5-3. 소스 반영 및 확인

이제 appcfg.py 를 이용하여 소스를 GAE 서버에 올린다. 처음 실행하면 gmail 계정 인증을 요청하고, 이후엔 .appcfg_cookies 파일을 만들어 인증을 생략한다.
다 올린 뒤 http://uw.appspot.com에 접속하면 화면이 잘 나온다. http://uw.appspot.com/hannal로 접속하면 http://www.hannal.net 로 이동한다.
6. 글을 마치며
기대보다 훨씬 재밌고 끝내주는 서비스, 아니 플랫폼이 등장했다. 시장에 미칠 파급력이 엄청날 것이라고 본다. 기획자도, 소프트웨어 엔지니어가 없거나 경험이 없어 서비스 확장 구조 설계에 어려움을 겪는 작은 팀이나 회사도 모두 매력을 느낄 개발 플랫폼이다.
그나저나 이런 것 나왔으니 가벼운 말로 꺼낸 django 개발 책을 정말 써야 하는 걸까? ^^