https://web.archive.org/web/20161129160024/http://www.xeschool.com/xe/xenote_module_book_contentwrite

BOOK Module dispBookContentWrite

영어 표현에서 Content는 "내용"을 뜻한다. 그리고 복수로 사용되는 Contents는 여러가지 내용을 가리키는 "목차" 또는 "목록"이 된다. 그래서 책의 맨 앞에 있는 목차를 "Contents"라고 표현하는 것이다. Write는 "글을 쓰다"라는 의미이다. 게시판에 새로운 글을 작성할 때도 Write라는 버튼을 보게 된다. 글이 모두 작성되면 "제출"이라는 뜻의 "Submit" 버튼을 보여주게 된다.

전송된 글의 내용은 조각 조각 나뉘어져 DB의 필드(field)에 채워진다. 이때 DB는 엑셀을 닮았다고 몇 번 이야기 했던 것 같다. 즉 데이터를 받는 한 칸이 필드(Field)이고 가로 방향의 행이 DB에서는 Row(행)가 된다. 또한 조각으로 분리된 데이터는 내용을 구분할 수 있는 변수명 아래로 채워지는데 이것이 Column(열)이다.

책의 정보를 입력하는 액션을 ContentWrite라고 했지만 DB의 입장에서는 가로 방향의 Row(행)을 추가하거나 수정하는 동작을 하게 된다. 이것이 Insert와 Update이다. ContentDelete 액션은 반대로 Row(행)을 삭제하는 동작을 하게 된다.

Insert와 Update를 위해 동작하는 dispBookContentWrite() 함수는 모두 write.html 템플릿 스킨으로 이동한다. 이때 책의 정보를 가지고 가느냐, 못가지고 가느냐는 책의 고유 식별 번호($book_srl)의 존재 여부에 따라 달라진다. 목록보기 화면에서 등록버튼을 클릭하게 되면 $book_srl의 값은 없다. 따라서 내용이 채워지지 않은 빈 폼(Form)을 보여주게 되고(3번), 보기(View) 화면에서 수정버튼을 클릭하게 되면 $book_srl의 값을 URL에 붙여 가지고 오기 때문에 책의 정보를 다시한번 확인(a-b-c)한 후에 내용을 미리 채운(d) 폼(Form)을 write.html 에서 보여주게 된다.

폼(Form)은 내용을 미리 채워놓든지, 빈 폼으로 값을 받든지 아무 상관이 없다. 다만 필터를 이용해 내용에 오류가 없는지 확인할 뿐이다. 검사를 마쳤으면 컨트롤러에게 값을 전달한다. 컨트롤러는 폼(Form)에게서 데이터의 값을 넘겨 받고 한가지를 확인해 본다. "$book_srl이 있을까?" 있다면 업데이트를 실행한다. 그런데 없다! 컨트롤러가 폼(Form)에게 물어본다. "야! 너 $book_srl의 값이 어디 있어?" 폼이 대답한다. "나도 몰라! 난 받은대로 전송(submit)했을 뿐이야! 내가 어떻게 알아!", "나참... 할 수 없지! 그냥 Insert로 보내야겠군! DB가 알아서 하겠지!"

DB는 $book_srl의 값이 없는 경우 무조건 Row(행)을 추가하고 $book_srl 필드의 값은 자동 증가시킨다. 만약 $book_srl의 값이 있다면 같은 값을 찾아 Row(행)를 수정(Update)한다. 모두들 시킨대로 잘 수행한다. 물론 내가 시킨일이다. 컨트롤러! 미안!!!

https://web.archive.org/web/20161129160024im_/http:/www.xeschool.com/xenote_page/images/book_mvc_dispBookContentWrite.png

  1. 프론트 엔드 뷰(View)

쓰기 권한을 체크한 후에 통과되면 URL에 따라온 책의 고유 식별 번호($book_srl)을 확인한다. 있다면 보기(View)와 같은 MVC를 실행한 후 $book_info 변수를 템플릿 스킨파일에 보내준다. $book_srl의 값을 찾을 수 없다면 새로 등록하기 위해 $book_srl의 값을 초기화하여 URL에 세팅한다.

book.view.php

검증을 위한 필터와 콜백함수의 처리 파일은 write.html 상단에서 임포트하여 사용할 수도 있지만 메소드 안에서 지정하여 사용할 수도 있다. 게시판(Board) 모듈을 참고해 보면 초기화(init) 부분에서 설정해 사용하기도 하는데 여기서는 입력과 수정에 따른 처리문만 있기 때문에 메소드 안에서 포함하도록 설정하였다. 만약 모듈의 전반적인 동작을 위해 사용되는 스크립트문이 있다면 초기화(init) 부분에서 포함시켜 사용하면 편리하다. 도서 정보를 새로 입력하거나 수정하기 위한 스킨 파일은 write.html 파일로 설정한다.

2. 입력/수정 스킨

$book_srl의 값에 존재 여부에 따라 Book Insert와 Book Update라는 텍스트가 변경되도록 설정하였다. 입력 필드의 값을 컨트롤러에 전송할 때 추가로 필요한 값은 hidden 속성으로 보낸다. 폼(Form)의 입력 필드 요소에서 value 속성은 $book_info의 값이 있는 경우 내용을 미리 채워 넣는 역할을 하게 된다. 만약 미리 채워진 값이 수정된다면 수정된 값을 전송하게 될 것이다. 폼(Form)이 전송되기 전 procFilter() 함수가 폼의 내용을 검사한다. 폼 검사 필터는 content_insert.xml 이 담당한다. 폼 검사 필터 파일과 콜백함수의 처리 파일은 프론트 엔드 뷰(View) 파일에서 이미 경로와 파일을 지정해 두었기 때문에 알 수 있다.

skins/default/write.html

3. 폼(Form) 검사 필터

폼의 입력 내용 중에서 원치 않는 문자열은 없는지, 채워지지 않은 필드는 없는지 확인해 본다. 필드의 내용 중에서 한글-영문-숫자만 입력되기를 원한다면 filter 속성을 korean_alpha_number와 같이 작성하면 된다. 검사가 완료되면 필터는 폼의 내용을 컨트롤러에게 보낸다. 그런데 필터는 어떻게 컨트롤러를 찾는 것일까? 액션(act)의 이름을 procBookContentWrite라고 설정하였다. 그러면 XE코어는 액션 명세서(module.xml)를 찾아 볼 것이다. procBookContentWrite는 타입(type) 속성이 컨트롤러(controller)이다. 따라서 book모듈의 컨트롤러(controller) 파일을 찾아 준다. 컨트롤러가 회신하는 값은 콜백함수(callback_func)을 호출한다. 콜백함수를 처리하는 JS파일은 이미 write.html에 로드된 상태이다. JS파일의 completeContentInsert() 함수를 호출하여 응답 받은 값을 전달하게 된다. XML 필터 파일의 문법은 개발자 메뉴얼을 참고한다.(p.55)

tpl/filter/content_insert.xml