닫기

전체보기

분야별
유형별
매체별
매체전체
무신사
월간사진
월간 POPSIGN
bob

컬쳐 | 리뷰

쉬운 업데이트를 위한 플래시 구축소스

2003-06-24

통념적으로 플래시 사이트는 다이나믹한 효과에 비해 업데이트가 쉽지 않다고 인식하고 있다.
플래시 사이트의 이러한 통념을 깨고 쉽게 업데이트가 가능하게 하고 클라이언트에게 비용적인 측면에서 부담을 줄일 수 있는 방식을 제공하는 것이 이번 싸이 사이트의 제작 의도이다.

이를 위해 싸이 사이트는 WYSWYG 방식의 멀티 미디어 관리자 툴이라는 개념을 도입하였다.
WYSWYG 방식의 멀티 미디어 관리자 툴이란 관리자가 플래시의 기술을 몰라도 사이트에 관리자 아이디로 접근했을 때, 컨텐츠의 수정과, 확인을 실시간으로 할 수 있는 방식을 말한다. 또한 관리자는 별도의 관리자 페이지에서 수정하는 것이 아니라 사이트 사용자와 동일한 페이지를 직접 접속하여 수정할 수 있다는 장점이 있다.
클라이언트는 이를 위해서 새로운 어플리케이션 프로그램을 구입해야 하는 추가 비용의 부담을 줄일 수 있도록 하였다. 이를 위해서 데이터를 XML로 처리하여 플래시에서 연동시킬 수 있도록 하였고, 일반적인 게시판은 플래시와 DB연동을 통해서 해결하고자 했다.

‘싸이’의 플래시 사용

이번 싸이의 공식 사이트는 전체 플래시로 작업되었다. 단지 플래시로 사이트만 만든 것이 아니라 관리자와 streaming music player, 게시판과 포럼, 회원가입 같은 각종 폼이 모두 플래시로 만들어진 것이다. 사실상 이미 플래시 사이트는 이미 많은 사람들이 보아왔던 것이지만 아직까지 플래시는 네비게이션이나 무비, 배너, 애니메이션 등 그 적용 분야가 상당히 고정적이고 정해진 부분들이 많았다. 항상 변해야 하고 업데이트 되어야 하는 사이트에서 전체플래시를 만든다는 것은 유지보수에 있어서 끊임없는 문제를 발생시키는 것이다. 따라서 이번 ‘싸이’ 프로젝트에서는 그런 부분을 해결함과 동시에 다른 많은 새로운 것들을 시도하였다. 이것은 기존 플래시 사이트와의 완전한 차별화를 이루고, 플래시를 이용한 사이트들의 전혀 새로운 활용사례가 될 수 있을 것이다. 이제 그 중에서 몇 가지 요소들을 하나씩 살펴보겠다.

XML이 적용된 컨텐츠

싸이의 사이트에서는 처음 홈페이지가 열리면 기본적인 XML 데이터들을 서버로부터 전송받는다. 그러면 플래시는 미리 주어진 데이터들과 전송 받은 데이터를 조합해서 화면을 구성해나가게 되는 것이다. 각 메뉴를 선택하면 해당 메뉴의 XML데이터들이 전송되고 플래시는 데이터를 기반으로 화면을 구성하게 된다. 이것은 단지 텍스트 리스트를 화면에 뿌려주는 것으로 끝나는 게 아니라 데이터의 유무와 내용, 사용자의 행동을 바탕으로 한 인터랙션이 이루어지게 된다. 예를 들어 NEWS에서는 뉴스리스트의 제목과 날짜 등을 전송 받아서 뉴스리스트를 화면에 나타내주고, 사용자가 선택한 뉴스의 내용을 보여주되 뉴스의 순서에 따라 네비게이션을 위한 버튼들이 보여지게 되는 것이다. MUSIC에서는 입력된 음반들의 데이터와 각 음반에 대한 정보들을 전송 받아서 음반리스트와 해당음반의 곡들을 보여주고, 사용자가 선택한 노래들로 플레이 리스트를 만들어 플레이어에서 음악을 들려주는 모든 일련의 과정이 XML과 그 데이터를 가지고 이루지게 된다.


// xml 로딩
loadXML = function() {
newsXML = new XML()
newsXML.ignoreWhite = true // 공백을 무시한다
newsXML.onLoad = loadEND; //로딩이 되면 loadEND함수를 실행한다
newsXML.load("news_newslist.xml")
}
loadXML() // XML데이터를 불러온다
//xml 데이타 해석
function loadEND() {
var topnode = newsXML.firstChild
var news_Data = topnode.childNodes
_global.news_total = news_Data.length //전체뉴스의 숫자
for (i=0; i < _global.news_total; i++) {
var listNum = Number(news_Data[i].attributes.num)
var varNews = news_Data[i].childNodes
var date = varNews[0].firstChild.nodeValue
var title = varNews[1].firstChild.nodeValue
_global["newsNum"+listNum] = listNum // 뉴스 리스트 번호
_global["newsDate"+listNum] = date // 뉴스 리스트 날짜
_global["newsTitle"+listNum] = title // 뉴스 리스트 제목
}
_global.news_totalpage = Math.ceil(_global.news_total / 5) // 전체 페이지 숫자
_parent.mc_articlelist.gotoAndPlay(2)
go_newslist()
delete newsXML


이것은 실제로 뉴스부분에 사용된 스크립트로서 XML을 전송 받고 데이터를 해석하는 부분이다. 이제 이렇게 받은 데이터를 갖고 플래시를 리스트를 뿌려주고 뉴스 내용을 보여주게 되는 것이다.


웹을 통한 실시간 업데이트 - 플래시 관리자

XML이 HTML과 가장 다른 점은 바로 정보의 구조화가 가능하다는 점이다. 그리고 그 점은 플래시에 적용했을 때도 마찬가지이다.
싸이의 사이트 중에는 플래시와 DB를 연동해서 만든 부분도 있지만 많은 부분이 XML을 활용해서 만들어졌다. 이것은 플래시가 XML을 받아들이고 해석할 수 있으며 XML을 만들 수도 있기 때문에 가능한 것이다. 컨텐츠의 내용을 XML로 구조화시켜서 각각을 데이터로 만들어 두고 이것을 플래시가 받아들이면 그에 맞도록 컨텐츠가 형성이 되어지는 것이다. 그러므로 컨텐츠를 업데이트 하기 위해서 일일이 디자이너가 플래시 프로그램을 열어서 작업할 필요가 없이 관리자가 그저 XML데이터만 변경해주면 플래시는 저절로 내용이 변하는 것이다.

여기에 덧붙여서 우리는 관리자 페이지가 입력 필드들만 나열되어 어떤 정보와 어떻게 연결되는지 알 수가 없는 기존 관리자와는 다르게 관리자가 실제 사이트에 접속해서 로그인하면 사이트 자체가 관리자 모드로 바뀌어서, 관리자는 언제 어디서든지 사이트에 들어와서 원하는 부분을 직관적으로 확인해가면서 업데이트 할 수 있도록 하였다.

여기서 직관적이라는 것은 누구라도 별도의 교육 없이 관리자로서 업데이트 시킬 수 있으며 업데이트한 내용이 즉시 화면에 보이므로 쉽게 작업이 가능하고, 웹에서의 실시간 업데이트이므로 별도 컴퓨터에서 관리자만 하던 작업이 언제 어디서든, 집에서든 PC방에서든 사이트의 관리가 가능하다는 것을 의미한다. 이런 일들이 가능해지는 것은 플래시가 XML데이타를 만들어낼 수 있기 때문인데, 관리자는 사이트에 접속해 로그인을 한 후 화면에 보여지는 내용을 업데이트하게 된다.

컨텐츠를 변경한다는 것은 곳 XML데이터를 변경한다는 것과 같은 말이 되므로 플래시는 변경된 데이터를 다시 서버로 보내서 해당 데이터를 저장하게 된다. 플래시에서 XML데이터를 만들어낼 수는 있지만 파일로서 저장하는 것은 하지 못하기 때문에 서버에는 데이터를 받아서 파일로 저장하는 간단한 서버 스크립트가 필요하게 된다.
관리자가 간단히 컨텐츠를 업데이트 한 후에는 사이트가 업데이트된 내용으로 보여지게 되는 것이다.



//XMLE데이타 만들기
function make_videoXML() {
psy_videomakeXML = new XML()
var topnode = psy_videomakeXML.createElement("video")
for (i=0; i<_global.video_totalNum; i++) {
var sub_data = psy_videomakeXML.createElement("list")
sub_data.attributes.thum = _global.video_thum[i]
sub_data.attributes.name = _global.video_title[i]
var sub_data_txt = psy_videomakeXML.createTextNode(_global.video_file[i])
sub_data.appendChild(sub_data_txt);
topnode.appendChild(sub_data)
}
psy_videomakeXML.appendChild(topnode)
//서버로 데이타 전송& 파일 생성
file_name = xml_folder+"psy_video.xml"
xml_txt = psy_videomakeXML
loadVariables("receve_data.asp", "", "POST");
//
delete file_name
delete xml_txt
trace("새로운 XML 데이타 psy_video.xml="+psy_videomakeXML)
delete psy_videomakeXML
}




이것은 실제로 PSY&FRIEND에 사용된 스크립트로서 비디오관련 데이터의 생성을 하는 부분이다. 관리자가 컨텐츠를 업데이트 하게 되면 플래시가 가진 데이터가 바뀌게 되고 이것들을 모아서 XML데이터를 만들어내는 것이다. 새로운 XML객체를 만들고 여기에 해당 데이터들을 하나씩 붙여나가는 과정이다. XML데이터가 생성되고 나면 이것을 서버로 보내는데 서버에 있는 'receve_data.asp'가 받아서 서버에 파일로서 해당 폴더에 저장을 하게 된다. 일단 데이터가 저장되고 나면 이후부터 사이트에 접속하는 사람들은 변경된 내용을 보게 된다.

스트리밍 뮤직 플레이어

플래시에서 사운드를 사용할 때는 이벤트사운드와 스트리밍 사운드로 나뉜다. 이것은 사운드를 임포트하여 플래시 내에서 사용할 때의 이야기지만 플래시MX에서는 음악파일을 스트리밍으로 플레이할 수 있게 되었다. 이번 프로젝트는 싸이의 사이트로서 음악을 플레이하는 것이 반드시 필요했고 따라서 우리는 스트리밍 방식의 플레이어를 만들게 되었다. 애초에 목표했던 모델은 윈엠프여서 윈엠프처럼 플레이리스트를 적용하며 사용자가 플레이리스트를 편집하며 원하는 대로 조절할 수 있도록 해주도록 했었고 어느 정도 목표한 만큼의 결과는 이루어 냈다. 음악파일을 스트리밍할 때의 문제점으로 일시정지 등의 일부 기능을 구현할 수 없었지만 기본적으로 관리자가 제공하는 플레이리스트와 사용자가 만들어내는 플레이리스트를 제어할 수 있도록 구현하였다. 플래시MX에서는 음악파일의 아티스트와 노래 제목 등의 정보가 들어있는 ID3태그를 읽어 들일 수 있으므로 그것을 활용할 수도 있겠지만 ID3태그는 파일의 맨 끝에 존재하므로 완전히 로딩된 후에야 읽어올 수 있으므로 사용할 수가 없었다. 따라서 플레이리스트에도 모든 데이터를 XML로 만들어 주게 되었다.
음악을 스트리밍할 때 플래시에서는 여러가지 정보를 표시해줄 수 있는데, 현재 플레이하는 시간, 전체 시간, 버퍼링되는 정도, 볼륨 등의 정보가 있다. 플래시에는 사운드 객체에 duration과 position속성을 읽어올 수 있는데 duration은 현재 버퍼링된 정도를 1/1000초단위로 알려주고 positio은 현재 플레이된 시간을 1/1000초단위로 알려준다. 그리고 음악을 스트리밍할 때 사운드객체에 로딩하게 되는데 이때 마치 로드무비시에 getBytesTotal()와 getBytesLoaded()를 통해 프리로딩을 만들 듯이 사운드객체에서도 음악파일의 전체 용량과 로딩된 크기를 알 수 있게 된다. 이런 정보들을 이용해서 음악을 플레이할 때 플레이어에는 각종 정보들이 나오게 되는 것이다.
아래의 스크립트는 실제 플레이어에 사용된 스크립트이다. 읽어온 데이터들을 환산하여 정보를 보여주고 있다.


// 플레이중인 음악의 정보 표시
time = function() {
this.createEmptyMovieClip("timeCheck", 100)
this.timeCheck.onEnterFrame = function () {
time = Math.floor(_root.mysound.duration / 1000) // 버퍼링된 시간을 초단위로 환산
info.playtime = Math.floor(time / 60) + ":" + time % 60 //버퍼링시간 표시
time2 = Math.floor(_root.mysound.position /1000) // 플레이된 시간을 초단위로 환산
info.nowtime = Math.floor(time2 / 60)+ ":" + (time2 % 60) //플레이시간 표시
if (time == time2) {
if (time2 != 0) { // 노래가 끝까지 다 플레이 되면 다음 곡으로 넘어간다.
next_mp3()
}
}
if (!playing) {
info.buffer_bar.gotoAndStop(0)
} else {
var total = _root.mysound.getBytesTotal()
var load_snd = _root.mysound.getBytesLoaded()
info.buffer_bar.gotoAndStop(Math.floor(load_snd / (total/100))) //버퍼링바 표시
}
}
}




플레이어에서 플레이리스트 기능을 구현하기 위해서 XML을 사용하였는데, 실제로 플레이의 제어는 아주 간단히 해결할 수 있다. 사운드객체를 만들고 그 객체에서 음악파일을 load하게되면 스트리밍이 시작되면서 일정량이 버퍼링되면 플레이되기 시작한다. 이전곡, 다음곡으로의 제어도 간단하여 그저 다음에 플레이할 곡을 사운드객체에 로딩하면 된다. 이때 다음 곡에 대한 정보를 보여주도록 한다.
또한 클라이언트의 요구로 게시판이나 기타 컨텐츠에 올려진 파일들에 대해서도 언제든지 플레이어로 들을 수 있도록 만들어야 했는데, 게시판 같은 곳에 올려진 음악파일을 선택하면 필요한 데이터를 플레이어로 보내줌으로써 간단히 해결할 수 있었다. 사용자가 작성한 리스트는 새로 만들거나 지우기 전에는 사이트에 있는 동안 항상 존재하므로 언제든지 다시 들어볼 수 있도록 하였다. 다음은 실제 음악을 플레이하는데 쓰인 스크립트이다.


// 음악 플레이
_global.play_mp3= function() {
playing = true // 플레이상태표시변수
stopAllSounds() //현재 플레이중인 모든 사운드 정지
_root.mysound = new Sound()
_root.mysound.loadSound(play_list[now], true) // 사운드 로딩
playList.title_str.text = title_list[now]+" : "+artist_list[now] //정보표시
bar_depth(1)
volume.setVol()
soundPan.setPanel()
}


DB 연동

웹의 많은 부분이 플래시가 차지하게 되면서 게시판도 플래시로 제작되어진 경우가 많다. 그러나 아직도 플래시 자료실 업로드 게시판은 그렇게 많이 보이지 않는다. 이번 싸이 프로젝트에서 만들어진 자료실 업로드 게시판, cartoon의 그림게시판, talk의 뉴스 게시판 등 이 모든 부분이 플래시로 제작되었다. 그동안 나온 플래시 게시판에서 소개되어지지 않은 부분을 소개하고자 한다. 먼저 회원 가입부터 알아보자.

1. 회원가입
기존의 단순한 플래시 회원 가입폼에서 벗어나 거의 완벽한 회원 가입폼을 만들었다. 간략한 기능 소개를 하면 주민번호 체크에서 일반 자바스크립트로 처리 하던 부분을 액션 스크립트로 체크 가능하며, 우편 번호 검색을 하여 원하는 주소를 찾아주는 부분과 이메일 적는 부분은 완벽한 형식으로 이메일을 적어야만 입력이 완성되게 하였으며 아이디 부분에서는 특수 문자를 적을 수 없게 하였다. 사용자 편의를 고려해 잘못된 기입에 대해서는 각각의 에러 메세지가 나오기 때문에 쉽게 입력을 할 수 있게 도와주고 있다.

▲ 회원 가입폼 화면

회원가입 스크립트 소스보기


//글적기
function on_submit() {
//각 버튼에 빈 문자열만 입력했을 경우
//입력된 문자열 개수 알기
//title 체크
t_s = id.length;
//빈 문자가 몇 개인지 카운트하기 위한 변수 초기화
c = 0;
//전체문자열을 검색
for (var i = 0; i //일일이 공백문자열인지 검색
if (title.substr(i, 1) == " ") {
//빈 문자열이면 카운트 올림
c++;
}
}
//버튼 공백인지체크
if (name == "") {
message = "이름을 적어주세요";
Selection.setFocus("name");
} else if (jumin1 == "" || jumin1.length<6) {
message = "주민번호 앞자리 6자을 적어주세요";
Selection.setFocus("jumin1");
} else if (jumin2 == "" || jumin2.length<7) {
message = "주민번호 뒷자리 7자을 적어주세요";
Selection.setFocus("jumin2");
} else {
//주민번호나 전번에 문자가 들어갔나 체크하고 이상 없으면 마지막으로 이메일 체크
intcheck(jumin1);
if (!intOk) {
Selection.setFocus("jumin1");
} else {
intcheck(jumin2);
if (!intOk) {
Selection.setFocus("jumin2");
} else {
//올바른 숫자이면 제대로 된 주민인지 체크하기
check_jumin(jumin1+jumin2);
}
}
}
}
//숫자만 입력했는지 체크하기 함수
function intcheck(in_txt) {
message = "";
txtCount = 0;
txt = in_txt;
for (var i = 0; i for (var k = 0; k<10; k++) {
if (txt.substr(i, 1) == String(k)) {
txtCount++;
}
}
}
if (txt.length == txtCount) {
intOk = true;
} else {
message = "문자가 들어갔습니다.";
intOk = false;
}
}
//주민번호 이상유무체크
function check_jumin(jumin) {
IDtot = 0;
IDAdd = "234567892345";
for (i=0; i<12; i++) {
IDtot = IDtot+int(jumin.substring(i, i+1))*int(IDAdd.substring(i, i+1));
}
IDtot = 11-(IDtot%11);
if (IDtot == 10) {
IDtot = 0;
} else if (IDtot == 11) {
IDtot = 1;
}
if (int(jumin.substring(12, 13)) != IDtot) {
message = "주민번호에 오류가 있습니다";
selection.setFocus("jumin1");
} else {
trace("이상없습니다");
//주민 이상없으면
//id체크
if (id == "") {
message = "ID 을 적어주세요";
Selection.setFocus("id");
} else {
strcheck();
if (strOk) {
if (pwd1 == "") {
message = "비밀번호을 적어주세요";
Selection.setFocus("pwd1");
} else if (pwd2 == "") {
message = "비밀번호을 적어주세요";
Selection.setFocus("pwd2");
} else if (pwd1 != pwd2) {
message = "비밀번호을 다시 한번 확인해주세요";
Selection.setFocus("pwd1");
} else if (tel1 == "") {
message = "지역번호을 적어주세요";
Selection.setFocus("tel1");
} else if (tel2 == "") {
message = "국번을 적어주세요";
Selection.setFocus("tel2");
} else if (tel3 == "") {
message = "나머지 번호을 적어주세요";
Selection.setFocus("tel3");
} else {
intcheck(tel1);
if (!intOk) {
Selection.setFocus("tel1");
} else {
intcheck(tel2);
if (!intOk) {
Selection.setFocus("tel2");
} else {
intcheck(tel3);
if (!intOk) {
Selection.setFocus("tel3");
} else {
if (zip1 == "" || zip2 == "") {
message = "우편번호 검색을 눌러주세요";
} else if (address2 == "") {
message = "나머지 주소을 적어주세요";
Selection.setFocus("address2");
//전체 문자열과 빈 문자열 카운트가 같음 다 빈 문자열이다
} else if (t_s == c) {
message = " 빈 문자열입니다, ^^";
Selection.setFocus("name");
} else {
//이메일 체크 이상없으면 저장
emailcheck();
if (emailOk) {
//trace("ok");
idcheck();
}
}
}
}
}
}
}
}
}
}
//id체크
function idcheck() {
gotoAndPlay("check");
loadVariablesNum(this.URL+"search_id.asp", 3, "POST");
}
//특수문자 체크하기
function strcheck() {
strOk = false;
var id_cnt = 0;
for (var i = 0; i ch = id.substr(i, 1);
trace(ch);
if (ch == "!" || ch == "@" || ch == "%" || ch == "^" || ch == "$" || ch == "#" || ch == "\\" || ch == "/" || ch == ":" || ch == "*" || ch == "?" || ch == "\"" || ch == "<" || ch == ">" || ch == "|" || ch == "'") {
id_cnt++;
}
}
if (id_cnt != 0) {
message = "회원 ID는 특수문자를 허용하지 않습니다.";
selection.setFocus("id");
} else {
var notid = id.substr(0, 1);
for (var i = 0; i<10; i++) {
if (notid == String(i)) {
var idcheckresult = "err";
break;
}
}
if (idcheckresult != "err") {
message = "";
strOk = true;
} else {
message = "첫 글자에 숫자가 올 수 없습니다";
selection.setFocus("id");
}
}
}
//올바른 이메일 체크 함수
function emailcheck() {
emailOk = false;
checktxt = email.indexOf("@");
checktxt2 = email.lastIndexOf("@");
checktxt3 = email.indexOf(".");
checktxt4 = email.lastIndexOf(".");
checktxt5 = email.indexOf(" ");
checktxt6 = email.substr((checktxt4+1), email.length);
if (checktxt5 != -1) {
message = "공백이 들어갈 수 없습니다.";
Selection.setFocus("email");
} else if (checktxt == -1) {
message = "@ 문자가 빠졌습니다";
Selection.setFocus("email");
} else if (checktxt != checktxt2) {
message = "@ 문자가 한 개 이상 사용되었습니다";
Selection.setFocus("email");
} else if (checktxt3 == -1) {
message = " . 문자가 빠졌습니다.";
Selection.setFocus("email");
} else if ((checktxt+1) == checktxt3) {
message = "@. 연속으로 사용할 수 없습니다.";
Selection.setFocus("email");
//} else if (checktxt3 != checktxt4) {
// message = " . 문자가 한 개 이상입니다.";
// Selection.setFocus("email");
} else if (checktxt == 0) {
message = "@ 앞에 문자열이 필요합니다.";
Selection.setFocus("email");
} else if (checktxt4 == (email.length-1)) {
message = " . 뒤에 문자가 필요합니다.";
Selection.setFocus("email");
} else if (checktxt6.length == 1) {
message = ". 뒤에 한 문자열 이상이 필요합니다.";
Selection.setFocus("email");
} else {
emailOk = true;
}
}



회원 가입폼에서 직접 사용되어진 스크립트의 일부분이다.

2. 자료실 게시판

플래시에서 파일 업로드는 쉬운 일이 아니다.
플래시 자체적으로 업로드 할 수 없기 때문에 자바스크립트를 사용하여 파일을 업로드 하게 하였다. 플래시에서 파일업로드 하기 위해 BROWSE 버튼을 클릭하면 숨겨진 html페이지에서 파일 업로드 폼이 나타난다. 파일을 선택하고 확인 버튼을 클릭하면 자바스크립트에서 플래시로 파일명을 보여준다. 입력을 마치고 전송 버튼을 클릭하면 다시 자바스크립트의 SUBMIT버튼을 클릭하게 하여 ASP파일로 폼 내용이 전송되게 하였다.

기존의 플래시 게시판에서 추가된 기능은 파일 업로드가 가능하고, 싸이의 홈이 가수의 홈이라는 점을 감안하여 음악파일처럼 용량이 3MB 이상 되는 파일도 업로드 가능하게 하였다. 그림(jpg)파일을 업로드하면 게시판에서 html형식의 그림이 그대로 보이게 하였으며 플래시 무비파일(swf)을 업로드 하면 게시판에서 플래시무비가 play 되어진다. 이 부분은 MX에서 새롭게 추가된 ScrollPane 콤포넌트를 사용해 해결하였다. 사용자 편의의 위해 글쓰기 및 삭제, 수정시 자동으로 회원가입 자료에서 읽어와서 비밀번호, 이름, 이메일 등을 체크하여 처리한다. 그림을 통하여 입력에서부터 업로드 과정과 업로드된 이미지가 보이는 과정을 살펴보자.

▲ 파일을 올리는 모습

▲ 파일 올리고 게시판에 보이는 모습

3. cartoon게시판

싸이의 홈에서는 카툰이 연재된다. 따라서 그림으로만 이루어지는 부분이 필요하다. 관리자가 전문 웹 제작자가 아닌 점을 감안하여 일반 웹폼에서 그림을 업로드하는 방식으로 하여 쉽게 카툰을 업데이트 하게 하였다. 관리자 메뉴에서만 업로드가 가능하며 작은 그림과 큰 그림부분으로 나누어 동시에 두 개의 그림파일을 업로드가 가능하다. 단순히 jpg 그림파일만 업로드하면 자동으로 카툰이 업데이트 되어 보여지게 된다. 이 부분도 자료실 게시판에서 변형된 형태이며, 그림만 보여지는 형태의 플래시 게시판이라고 보면 된다.

▲ 관리자 상태에서 그림을 올릴 수 있는 폼이 보인다.


4. talk 게시판
커뮤니티 사이트로 만들어 달라는 클라이언트의 요청으로 토크부분만 상당한 수정을 하였다. 왼쪽 리스트부분을 보면 뉴스 같은 형태로 처리가 되며, 오른쪽 내용이 보이는 부분은 메인 뉴스와 글을 읽은 사용자가 자기의 의견을 적을 수 있는 commant 부분이 있다. 그림과 파일을 업로드 가능하며, 관리자가 음악 파일을 올리면 사용자는 파일을 클릭하여 싸이 홈에서 만들어진 mp3player가 자동으로 음악을 들려주게 된다. 싸이의 홈은 관리자가 쉽게 업데이트 될 수 있도록 배려했으며, 사용자 편의의 위해 글쓰기 및 삭제, 수정 시 자동으로 회원가입 자료에서 읽어와서 비밀번호, 이름, 이메일 등을 체크하여 처리한다.

▲ 토크부분에서 보여지는 모습


facebook twitter

당신을 위한 정글매거진