Blog

  • 코드 행복론

    코드는 행복해야 한다. 그 클래스나 모듈 내에서 코드가 행복해 하면 좋다고 생각한다. 물론 어떤 것이 행복하냐? 물으면 그건 프로그래머 각자의 생각에 따라 다루겠지. 서로의 시각이 다르니, 같은 코드라도 다른프로그래머의 각각 다른 시선으로 “필터링” 되면 쓰레기가 될수도, 진주같이 빛나는 코드가 될 수 있다. 애매모호하다. 코드는 논리적이다. 그래서 대부분의 경우 확실하게 잘잘못을 나눌 수 있는 명제의 문제가 많다. 그러니 코드의 “행복론”이라니 이건 너무 추상적이지 않은가? 헛소리이지 않은가? 맞다. 헛소리 같다.

    그렇지만 그래도 이런 행복론은 왠지 멋져 보인다. 허황되지만 은근 믿어 보고 싶다. 아, 그리고 아주 완곡하게 이야기해 보자. 코드는 프로그래머의 산물이다. 내가 프로그래머라면, 내가 짠 코드는 내 자식과 같은 것이다. 내 새끼들은 그래도 잘나고 멋있기를 바라는 것이 부모의 심리다. 나도 가능하면 내 코드가 잘나고 멋있었으면 좋겠다.

    또 코드에 정답과 오답이 언제나 칼로 자르는 것처럼 나누어지냐고 한다면 또 그건 아니다. 아까와는 정반대의 이야기를 하니 모순 같지만 약간 차원이 다른 이야기다. 그러니까 이거다. 코드가 풀려고 하는 문제의 풀이 과정(알고리즘)은 정답이냐 오답이냐를 딱 잘라 이야기할 수는 있지만, 그 정답의 도출 과정은 제각각이다. 답이 여럿일 수 있다. 알고리즘이 아닌 방법론 차원으로 올라가면 프로그램은 세상만사처럼 딱 잘라서 선악 참거짓 우열을 가리기 어려워질 수도 있다. 예를 들어 프로그래밍 패턴 같은 것이다. 어떤 문제에 대한 어떤 패턴은 영 아니지만 어떤 패턴은 잘 맞는다. 한편 어떤 문제에 대해서는 다양한 해결 패턴이 존재할 수도 있다. 애매모호해지는 것이다. 괜히 프로그래밍이 우스갯소리로 “도 닦는 직업”이라고 하는 게 아니다.

    그런 와중에 문득 행복론이란 생각이 들었다. 그래서 이 메모를 장황히 적고 있다. 사람은 어떻게 살아야 할까 고민을 한다. 많은 현명한 이들이 “행복”을 중요한 가치라고 조언해 주었다. 그래 행복하면 좋지.

    엉뚱한 생각이 떠올랐다. 코드가 만약 사람이라면? 내가 짠 내 새끼들이 살아 숨쉬는 생물이라면? (머신 속에서 개념적으로 살아 숨쉬기는 하지. 우리는 이걸 개채화-instantiation라고 부른다.) 그러면 그 애들은 과연 행복할까? 살고 죽는 (생명 주기) 짧디짧은 순간을 행복하게 보내고 있을까?

    내 멋대로 그런 가치를 사람의 행복론에서 따 와서 상상해 보았다. 뭐 잡동사니같은 생각인데, 괜히 멋지구리해 보였다. 코드가 행복해 한다? 어떻게 행복해할지는 지금은 잘 모르겠지만 직감적으로는 뭔가 작은 실마리 같은 게 잡힌다고 느낀다. 착각일 수도 있지만서도.

  • 테마를 별도의 디렉토리로 옮기기

    개발 의도상 테마를 별도의 디렉토리에 두고 싶은 생각이 들었다. 플러그인을 놓고 쓰는 것처럼 말이다. 그런데 wp-config.php 코덱스를 참고해도 플러그인의 경로를 바꾸는 일은 허용되나, 테마에 대해서는 이런 설정이 공식적으로는 존재하지 않는다. 테마를 별도로 쓰려면,  wp-contents 디렉토리를 벗어나지 않는 한에서 변경하기를 권장하기도 한다.

    사실 실사용 서버에 이런 일을 할 필요는 없다. 단지 개발 서버상에서만 편하자고 하는 일이다.

    나는 코어와 플러그인의 디렉토리를 분리해서 사용한다. 이렇게 해서 여러 사이트에 대해 개발을 할 때 단 한 벌의 코어로 대응할 수 있다. 이렇게 사용하는 법은 다른 포스트를 통해 소개한 바 있다.

    테마 디렉토리는 플러그인과 같은 레벨에 둔다고 가정한다.  그리고 MU 플러그인을 하나 만들고 거기에 그냥 다음과 같이 적으면 된다.

    register_theme_directory( dirname(__DIR__) . '/themes' );

     이렇게 하면 이동한 테마 디렉토리에 있는 테마 목록이 워드프레스 ‘외모’메뉴에서 보이게 된다.

    그런데 이렇게만 하면 문제가 발생한다. 왜냐하면 이 시점에서 정적 자원들을 웹서버로 접근할 때의 URL이 정해지지 않았기 때문이다. 테마가 나오지만, 이미지나 자바스크립트는 404 에러를 내면서 죽을 것이다. 당연히 웹서버에 현재 /themes 디렉토리에 대해 URL로 접근할 수 있도록 처리해야 한다. 플러그인의 WP_PLUGIN_DIR과 WP_PLUGIN_URL 설정이 두 개로 나뉘어져 있는 것과 동일한 이치다.

    이 때는 아래와 같은 필터를 통해 해결할 수 있다.

    add_filter( 'theme_root_uri', function( $theme_root_uri, $site_url, $stylesheet_or_template ) {  
      $theme_root_path = dirname( __DIR__ );
      if( strpos( $theme_root_uri, $theme_root_path ) === 0 ) {
        return substr( $theme_root_uri, strlen( $theme_root_path ) );
      }
      return $theme_root_uri;
    }, 10, 3 );

     합쳐진 MU 플러그인의 레시피는 아래와 같다. 단, 완벽한 동작을 보장할 수 없으니 개발용으로만 참고하시라.

    <?php
    
    add_filter( 'theme_root_uri', function( $theme_root_uri, $site_url, $stylesheet_or_template ) {  
      $theme_root_path = dirname( __DIR__ );
      if( strpos( $theme_root_uri, $theme_root_path ) === 0 ) {
        return substr( $theme_root_uri, strlen( $theme_root_path ) );
      }
      return $theme_root_uri;
    }, 10, 3 );
    
    register_theme_directory( dirname(__DIR__) . '/themes' );
    

     

  • 특정 포스트의 권한을 제어하는 레시피

    User Role Editor 보다 더욱 세밀한 권한 체크를 진행시킬 수 있는 레시피. ‘user_has_cap’ 필터를 잘 활용하면 된다.

    좀 더 구체적인 예로 설명을 하자. 만일 내가 포스트 아이디 1141번을 임시 글로 등록해 두었다고 가정하자. 그리고 단지 이 포스트에 대해서만은 editor들은 편집을 허용하지 않게 만들고 싶다. 그렇다면 다음처럼 코드르 만들 수 있다. 커스텀 포스트 타입은 ‘music_collection’이고 적절히 이에 따라 권한 세트를 생성했다.

    add_filter( 'user_has_cap', 'my_user_has_cap', 10, 4 );
    
    function my_user_has_cap( $all_caps, $caps, $args, \WP_User $user ) {
    
      if ( sizeof( $caps ) && in_array( $caps[0], array( 'edit_music_collections', 'edit_others_music_collections' ) ) ) {
    
        if ( sizeof( $args ) >= 3 && $args[2] == 1141 ) {
    
          if ( $user->has_cap( 'editor' ) ) {
    
            unset( $all_caps[ $caps[0] ] );
          }
        }
      }
    
      return $all_caps;
    
    }

     콜백 함수는 4개의 인자를 가지고 있으며, 이 인자의 확인이 은근히 복잡하다. 디버깅 및 설명의 편의를 위해 하나의 if로 처리하지 않고 3개의 if로 잘라 넣었다. 실전 코드에서는 당연히 하나로 붙이도록 하자.

    첫번째 if는 현재 요구되는 primitive 권한을 체크한다. 어떤 커스텀 포스트에서 요구하는 권한이 내가 제어하고 싶은 범위의 것인지를 검사한다.

    두번째 if는 특정 단일 포스트에 대한 권한 요구인지, 아니면 전반적인 복수의 포스트에 대한 요구인지를 체크한다. args에 인자로 0번째는 매핑되기 전의 권한 템플릿 이름, 1번째는 유저의 ID, 2번째로 post의 ID가 있다. 이 부분이 매우 중요하다. 단일 포스트의 권한 검사이므로 args 길이는 3이상이어야 한다.

    세번째 if에서 다시 사용자의 권한 체크를 한다. 지금 권한 체크에 대한 콜백 함수인데, 다시 권한 체크를 재귀적으로 부르고 있다. 권한 필터링을 실제 구현하는 것이 은근히 쉽지 않음을 짐작할 수 있다. 물론 익숙해지면 이야기는 다르겠지만, 주 역할과 메타 역할의 개념 등등을 잘 이해하지 못하면 이 권한 체크에 번번히 실패할 가능성이 높다.  재귀 함수의 오버헤드를 줄이려면 바로 $user->caps 를 활용할 수도 있다.

    이렇게 설정하면,  edtor들은 1141번 포스트에 대해 다음과 같은 화면을 만나게 된다.

    특정 포스트를 특정 권한에게 접근 제한했을 때의 결과 예제 스크린샷

    글에는 두 가지 draft가 있다. 첫번째 draft는 편집이 가능하지만, 두번째 draft는 접근이 막혀 있다. 이렇게 단일 포스트 단위로 접근을 제어하는 방법은 우리가 흔히 접할 수 있는 user role editor로도 쉽게 구현하기 어려운 기능이다. 게다가 코어의 자연스러운 접근 권한 체크를 하기 때문에 엉뚱한 곳에서 적당히 땜빵 코드로 접근을 막는 것보다 더욱 확실하고 자연스러운 제어가 가능하다. 스크린샷으로도 보이듯 접근 제어가 안 되는 항목은 확실하게 UI적으로도 막혀 있는 것이 보인다. 이렇게 구현하면 예상치 못한 URL로 접근하더라도 코어가 확실히 접근을 차단해 줌을 기대할 수 있는 것이다.

    물론 보통은 커스텀 포스트에 이 정도로 세밀한 접근 제어 기능을 구현하지는 않으나, 이와 유사한 요구 사항은 실무에서 많이 발생할 수 있을 것이라 생각한다. 이걸 자유자재로 사용할 수 있다면 정말 훌륭한 플러그인 구현이 되리라 생각한다.

    워드프레스의 역할과 권한은 잘 이해하는 사람도 흔치 않을 것 같다 코드가 지저분하든 더럽든 어쨌든 간에, 나는 워드프레스가 훌륭한 CMS라고 생각하며 그 근거 중의 하나로 이 강력하고 유연한 역할과 권한 시스템을 든다.  이걸 사용자가 쉽고 간편하게 쓸 수 있는 UI가 없는 것은 아쉽지만 (아니, 그런 UI를 쉽게 사용하게 만드는 것 자체가 미친 난이도지만) 이러한 시스템이 기저에 있다는 것 자체가 놀라움이다.

    덧글 ) 권한 체크는 상당히 어렵다. 비활성화된 항목에 마우스를 가져다 대어 보자.

    어이쿠, 이게 뭔가. Trash? 편집은 못하지만 지울 수는 있다. 편집자 역할은 휴지통에 있는 글도 영구 삭제 가능하다. 물론 같은 스태프끼리 그럴 일은 없겠지만… 아, 권한 체크는 세심해야 함을 강조한다. 해당 권한 목록을 꼼꼼하게 살펴서 이런 구멍이 없도록 잘 대비하기를 권한다.

  • 어드민 화면의 열 수를 1개로 고정하는 레시피

    add_filter( 'screen_layout_columns', function ( $columns ) {
      $screen = get_current_screen();
      $columns[ $screen->id ] = 1;
      return $columns;
    } );
    
    add_filter( 'get_user_option_screen_layout_kpm_paper', function ( $value ) {
      return 1;
    } );
    
    add_action( 'in_admin_header', function () {
      $screen = get_current_screen();
      if ( $screen->id == 'kpm_paper' ) {
        $screen->remove_option( 'layout_columns' );
      }
    } );

     커스텀 포스트에 활용할 수 있다.

     

  • 안녕 iPhone 4S

    2017년 02월 18일 토요일자로 6년간 사용한 아이폰을 교체했다. 갤럭시 A5 2017 모델이 이제 내 새로운 폰이 되었다.

    그동안 많은 일을 같이 겪어준 폰인데, 물건에 감정을 너무 쓴 걸까? 마음이 짠하다. 대학원 때, 아르헨티나 때, 귀국 후 인턴, 게으른 프리랜서(?), 일산 고시원 시절하며 최근에 이르기까지… 늘 내 손, 호주머니, 가방에 있었던 녀석이었다.

    그렇지만 이제는 너무나 느려지고, 한 번 갈았던 배터리도 시원찮아졌다. 추억은 많지만 더 이상은 같이 하기 어려울 것 같다. 일산 원룸으로 옮기고 나서 인터넷 사정이 그닥 좋지 않은데, 후진 3G 망으로는 도저히 인터넷 사용량을 감당할 수 없었다.

    언젠가는 애플 휴대폰을 다시 쓸 날이 올 거라 생각한다. 일산에 와서 많은 것이 새롭게 변해 간다. 새로워지는 일은 나쁜 일은 아니지만, 익숙한 것을 버린다는 것은 상당히 자주 짠한 감정을 가져 와서, 그걸 안고 가기 버거울 때가 많다. 쓸데 없이 감상적이다. 밤이라 그렇다.

    그래 안녕 내 아이폰 4S, 오늘까지 나랑 같이 있어 줘서 정말 고마웠어.

     

  • 워드프레스 플러그인 개발 세팅

    팁이라고 하기는 너무 거창하고… 현재의 내 상태를 기록해 두는 뜻으로 포스팅을 해 봅니다. 워드프레스를 개발할 때 즐겨 사용하는 세팅을 기록합니다. 고도로 숙련된 세팅이라고 할 수는 없으니, 저 아닌 다른 분들은 “아, 얘는 이런 식으로 쓰는 구나” 하고 참고만 해 두셨으면 합니다.

    기본 환경

    OS

    OS는 리눅스 민트를 사용합니다. 리눅스 중에서는 가장 대중적이고, 무탈하고 쓰기 편합니다. 여러 리눅스 OS를 거쳐가며 삽질을 해 봤지만, 초기 부팅 및 설치 후 사용성까지 생각하면 민트를 따라잡을 OS는 없다고 개인적으로 생각합니다.

    윈도우 10이 리눅스 서브시스템을 지원하고, 윈도우에서 apt나 bash를 실행시킬 수 있도록 많이 변화하기는 했지만, 아직 안정적이라고 볼 수 있는 단계는 아닙니다. 개인적으로 윈도우는 게임을 할 때 사용하는 OS로 굳어져 있습니다.

    물론 맥OS도 좋은 개발 환경을 제공합니다만, 리눅스를 택하는 이유는 강력한 패키지 매니저 때문이죠. apt로 엄청나게 빠르고 편하게 패키지 설치를 할 수 있습니다. 개발 환경은 이렇게 무난하게 꾸미는 것이 최선이라고 생각합니다.

    옵션: Vagrant

    한때는 vagrant를 활용해서 개발 환경 세팅은 모두 vagrant를 활용한 가상 OS에 밀어 넣은 적이 있었습니다. 이것은 이것대로 엄청난 장점이 있죠. Provision 스크립트를 미리 만들어 둔 덕에, 초기 개발 환경 세팅이 단 2~3분안에 뚝딱 끝나는데다, 항상 균일한 환경을 유지할 수 있다는 점은 엄청나게 매력적이었습니다. 이 때는 가상 OS로 우분투 서버를 사용했습니다. 소스 코드, 웹브라우저, IDE는 호스트에 놓이고, 개발 환경만 게스트에 놓이도록 만들었습니다.

    하지만 장점에는 단점도 있는 법. 개인적인 개발을 할 때는 조금 불편한 면이 종종 있었습니다. 호스트와 게스트는 별도의 OS라, 제대로 IDE에서 디버깅을 하기 위해서는 두 OS간 프로젝트의 경로 매핑이 필요합니다. 플러그인을 새로 제작할 때마다 경로 매핑을 하는 거나, 호스트와 게스트의 경로를 각각 숙지해야 하는 점은 좀 짜증나더군요.

    개인적으로 워드프레스 플러그인 개발을 위해서 이렇게까지 vagrant 까지 도입해야할 필요성은 좀 없지 않나 하여 이제는 쓰지 않습니다.

    개발 스택

    Apache 2.4, PHP, MySQL을 사용합니다. 세 콤포넌트 모두 패키지 관리자의 기본 환경을 사용하고 있습니다. 개발 환경에서 그렇게 세세하게 세팅을 할 이유가 없다고 생각하기 때문에 nginx나 mariadb는 그렇게 고려하지 않고 씁니다. 가상호스트 설정 등등에서 apache가 세팅하기 수월하며,  debian 설치 관리자 apt에서는  mysql-server 패키지를 설치할 때가 mariadb-server 패키지를 설치할 때보다 훨씬 간결하게 설치가 끝납니다. phpmyadmin 또한 설치 명령어 한 방에 끝납니다.

    참고로 우분투 14.04에서는 PHP 5.6이 기본이지만 16.04에 와서 PHP 7.0이 기본입니다. 원한다면 리포지터리를 추가해서 가장 최신의 PHP 버전을 설치할 수도 있습니다. 소스 컴파일 설치는 별로 선호하지 않습니다.

    IDE

    에디터로 Atom이나 Sublime Text도 선호되고 있지만, 저는 IDE는 PhpStorm을 사용하고 있습니다. 몇 년째 사용 중인 훌륭한 IDE입니다. 제게는 다른 대안이 없습니다.

    워드프레스를 위한 레이아웃

    플러그인을 몇 번 제작해 보니 경로를 조직적으로 구성하는 편이 효율적으로 보였습니다. 그래서 머리를 굴려 나름 레이아웃을 구상해 보았습니다.

    기본적인 경로는 이렇게 되어 있습니다. .php, .dist 확장자를 제외한 항목은 모두 디렉토리입니다.

    .
    ├── apache2
    ├── bin
    ├── db-conf.php
    ├── db-conf.php.dist
    ├── niu-plugins
    ├── plugins
    ├── scripts
    ├── wp-config.php
    ├── wp-core
    └── wp-settings

    apache2 디렉토리

    각 워드프레스 환경은 아파치의 가상호스트로 구분합니다. 각 호스트는 apache2 디렉토리 안에 .conf 파일을 두어 설정합니다. 이 설청 파일을,  /etc/apache2/sites-available에 심볼릭 링크를 걸고, a2ensite로 활성화 시켜 줍니다. 아래 코드는 예입니다.

    ln -s ./apache2/wordpress-vhosts.conf /etc/apache2/site-available
    sudo a2ensite wordpress-vhosts.conf

     이렇게 하면 본래 wordpress-vhosts.conf는 내 계정 소유의 파일이기 때문에 일일이 관리자 권한 없이도 편집이 가능하죠.

    아파치 가상호스트 설정

    wordpress-vhosts.conf 파일은 비교적 단순하게 구성하면 됩니다. 예입니다.

    Alias /plugins <path-to-root>/plugins
    <Directory "<path-to-root>">
      Require all granted
      Options +FollowSymlinks -Indexes
      AllowOverride All
      php_admin_value open_basedir "<path-to-root>"
    </Directory>
    
    #####################################################################
    <VirtualHost *:80>
      ServerAdmin  <email>
      DocumentRoot <path-to-root>/wp-core/4.7.1
      ServerName   wp.4.7.1
      ServerAlias  wp.latest
      ErrorLog  ${APACHE_LOG_DIR}/wp.4.7-error.log
      CustomLog ${APACHE_LOG_DIR}/wp.4.7-access.log combined
    </VirtualHost>
    
    
    #####################################################################
    <VirtualHost *:80>
      ServerAdmin  <email>
      DocumentRoot <path-to-root>/wp-core/4.6.2
      ServerName   wp.4.6.2
      ErrorLog  ${APACHE_LOG_DIR}/wp.4.6.2-error.log
      CustomLog ${APACHE_LOG_DIR}/wp.4.6.2-access.log combined
    </VirtualHost>
    
    # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
    

    이후 다시 설명하겠지만, 위 코드는 워드프레스를 버전별로 수동 관리하는 케이스입니다. 각 버전별로 “http://wp.<버전 번호>/” URL로 접근하도록 처리했습니다.

    bin 디렉토리

    wp-cliphpunit 같은 바이너리 파일을 여기에 두었습니다. wp-cli는 사용할 때마다 헷갈립니다만, 가끔씩 워드프레스 동작을 스크립트화 해 두기에는 좋을 겁니다.

    niu-plugins 디렉토리

    디렉토리 중 mu-plugin (must-use plugin)이라고 해서, 항상 사용하는 플러그인을 넣어 두는 곳이 있습니다. 그걸 따서 niu-plugin (not-in-use plugin) 디렉토리를 별도로 만들었습니다. 큰 의미는 없고 잠시 사용하지 않을 플러그인을 이 쪽에 놓아 둘 목적으로 만든 것입니다. 활성/비활성 차원이 아니라 아예 존재를 이 쪽으로 옮겨 두는 거죠.

    plugins 디렉토리

    플러그인만 이 곳에 놓아둡니다. 모든 워드프레스 개발 사이트는 이 플러그인을 공유합니다. 활성/비활성으로 적절히 조절하면 되니까 이렇게 몽땅 놔두는 것도 큰 문제가 없습니다.

    scripts 디렉토리

    wp-cli를 위한 bash-completion 스크립트나 유용한 쉘 스크립트들을 저장하기 위한 디렉토리입니다.

    wp-core 디렉토리

    워드프레스의 코어가 여기 있습니다. 코어를 관리하는 방법은 크케 나눠 두 가지가 있습니다.

    1. 1벌의 코어를 직접 디렉토리 아래에 두고, 워드프레스에서 코어 업데이트가 발표되면 같이 따라간다.
    2. 버전별로 코어를 관리. 업데이트는 막되, 버전별로 하위 디렉토리에 위치.

    코어 버전이 업데이트될 때 종종 데이터베이스도 업데이트됩니다. 큰 변화는 별로 없지만,  그래도 테이블이 한 번 업데이트되면 되돌리기 어렵습니다. 개인적으로는 예전에는 단순한 까닭에 1번 방식을 썼는데, 버전별 차이에도 좀 대응하고 싶어 이제는 손이 좀 더 가더라도 2번을 쓰려고 합니다.

    wp-settings 디렉토리

    도메인별 워드프레스 설정을 놓아두는 디렉토리입니다.

    워드프레스 설정

    wp-config.php 파일은  워드프레스 코어에 있어도 되지만, 보안상 코어 하나 위 디렉토리에 두어도 무방하도록 되어 있습니다. 여러 사이트가 특별히 각자의 세팅을 가질 필요 또한 크지 않으므로 wp-core의 상위 디렉토리에 wp-config.php 파일을 위치시켰습니다.

    만약 버전별로 코어를 관리하는 경우, wp-core 하위에 각 버전별 코어가 위치하므로 wp-congif.php가 1계층이 아닌 2계층 차이가 납니다. 이 때에는 wp-core 디렉토리에 wp-config.php의 심볼릭 링크를 설정해 주면 됩니다.

    도메인과 세팅 경로

    서버 도메인인 $server_name 변수와 세팅 디렉토리를 얻는 코드를 둡니다.

    $server_name  = $_SERVER['SERVER_NAME'];
    $setting_path = __DIR__ . "/wp-settings/{$server_name}.php";
    

     플러그인 경로와 URL

    설정 파일에서 중요한 것은 공통의 플러그인 경로를 지정하는 것입니다. 그러므로 다음과 같은 플러그인 설정을 넣습니다.

    define('WP_PLUGIN_DIR',   __DIR__ . '/plugins');
    define('WP_PLUGIN_URL', "http://{$server_name}/plugins");
    

    디버깅 환경 설정

    개발 환경이므로, 디버깅은 항상 켜 둡니다. 단, 디버깅 용 로그를 웹브라우저로 띄우면 화면이 매우 지저분해지므로 로그로만 볼 수 있도록 만듭니다. wp-content 디렉토리는 기본적으로는 각 코어별로 사용하도록 두었으므로 로그 파일은 각 <코어>/wp-content/debug.log가 됩니다. 스크립트 디버깅도 켜 둡니다.

    define('WP_DEBUG', true);
    define('WP_DEBUG_LOG', true);
    define('WP_DEBUG_DISPLAY', false);
    define('SCRIPT_DEBUG', true);

     기타

    포스트 리비전이나 업데이트 관련 사항을 세팅해 두면 됩니다. 코어를 수동으로 관리한다면 자동 업데이트 항목도 꺼 두어야 할 것입니다.

    define('WP_POST_REVISIONS', 0);
    define('AUTOMATIC_UPDATER_DISABLED', true);
    define('WP_AUTO_UPDATE_CORE', false );

    이렇게 해도 워드프레스 코어를 업데이트하라는 알림이 관리자 화면에 출력될 수 있습니다. 워드프레스 업데이트를 완전히 꺼 두는 플러그인이 있습니다. 이런 플러그인을 활용해 혹시 실수라도 업데이트를 진행하지 않도록 처리하면 좋겠죠.

     도메인별 세팅

    도메인별로 다른 데이터베이스 테이블을 관리할 수도 있고, 또 모든 도메인이 같은 테이블을 공유할 수도 있습니다. 그러나 버전별로 워드프레스를 관리하려면 반드시 버전별로 다른 테이블을 사용해야 합니다. 앞서 말씀드렸듯 워드프레스 버전마다 데이터베이스 버전도 달라자기 때문입니다.

    버전별로 워드프레스를 관리하기 위해 다음과 같은 도메인 규칙을 만들었습니다.

    wp.<워드프레스 버전>

    그러므로 워드프레스 4.6.2 버전은 “http://wp.4.6.2/”, 4.7 버전은 “http://wp.4.7/”로 접속합니다.

    물론 이렇게 하려면 /etc/hosts 파일에 해당 도메인으로 접속할 수 있도록 추가해야 합니다.

    127.0.0.1 wp.latest wp4.7 wp.4.6.2 wp4.6.1

    그리고 wp-settings/wp.4.6.2.php, wp-settings/wp.4.7.php 같은 도메인 이름과 같은 php 파일을 두고, 그 안에 도메인별 설정을 넣으면 됩니다.

    코어 하나만을 사용하는 경우에도 비슷합니다. /etc/hosts 파일 안에 각 도메인에 IP를 127.0.0.1로 대응시키고, wp-settings/<domain>.php 파일을 만들면 됩니다.

    설정 파일에는 최소 하나의 변수가 있어야 합니다. 아래는 그 예입니다.

    <?php 
    $table_prefix = 'wp471_';

    마치며

    위 설명한 구조는 제 github repository에 있습니다. 손은 좀 가지만 그리 어려운 것은 아니므로 다운로드 받아서 한 두번 살펴보면 쉽게 파악할 수 있을 것입니다.

    그리고 이 곳에 우분투 16.04 서버를 위해 만든 provision 스크립트가 있습니다. 개인적으로는 APM 설치 및 세팅에 알찬 도움이 되고 있습니다.

    테마는 제가 잘 다루지 않으므로 이 레이아웃이 테마까지 효율적으로 관리할 수 있을지는 모르겠습니다만, plugins 디렉토리를 응용해 테마 디렉토리를 별도로 관리한다면 플러그인과 큰 차이는 없을 것이라 생각해 봅니다.