[작성자:] changwoo

  • 워드프레스 자동 설치 스크립트 샘플

    이번 포스팅은 특정 디렉토리를 기준으로 DB 생성, 소스 다운로드, 설치 및 초기 셋팅을 정해진대로 수행하는 스크립트의 예제를 올린다.

    그동안 간단히 만들어 사용한 거고 WP-CLI를 사용하는 좋은 예시인 것 같다. 코드는 gist 에서 확인할 수 있다.

    이 코드에서 처음에 지정해 줘야 할 변수값들이 있다. 확인해 보자.

    WP_ROOT="/path/to/wp/root"
    DB_ROOT_PASS='0000'
    
    ADMIN_USER=user
    ADMIN_EMAIL=user@email.com
    ADMIN_PASS=pass
    
    SMTP_USER=user@gmail.com
    SMTP_PASS=passCode language: JavaScript (javascript)

    WP_ROOT은 워드프레스 설치들을 모아놓은 상위 디렉토리이다. 여기가 만약 /home/changwoo/develop/wordpress였다면 이 디렉토리의 서브디렉토리별로 워드프레스 설치본이 하나씩 생성된다.

    ADMIN_USER, ADMIN_EMAIL, ADMIN_PASS는 워드프레스 최초설치시 생성하는 관리자의 로그인, 이메일, 패스워드가 된다. 적절히 셋팅해두자.

    SMTP_USER, SMTP_PASS는 기본으로 지메일 SMTP 세팅을 정해두고, 사용자와 패스워드를 입력한다. 지메일 계정의 낮은 보안 앱 접근을 허용해 두어야 하는 것을 잊지 말자.

    중간에 내가 사용하는 naran 프로젝트 플러그인 몇가지도 추가되어 있다. 이것을 정상적으로 실행하려면 git이 설치되어 있어야 한다. 또한 WP CLI를 기본적으로 사용하므로 반드시 설치되어 있어야 하고.

    wp_install 스크립트는 다음과 같이 실행될 것이다.

    $ wp_install foo
    ... (설치 메시지)
    Successfully installed. DB USER/PASS: foo / IDLcKVrGJ4Ju

    예를 들어 WP_ROOT/home/changwoo/develop/wordpres였다면 이 아래 foo라는 디렉토리 아래 워드프레스가 설치된 것이 보일 것이다. 그리고 이 워드프레스의 도메인은 http://foo.dev.site로 설정되어 있다. 나머지 서버 설정은 따로 진행하면 된다.

    스크립트는 예시일 뿐이다. 각자의 환경에 따라 적절히 변경해서 사용하도록 하자.

    wp_install gist

  • wp-cli 사용하기 #3

    어제의 포스팅에 이어 wp-cli에 대해 소개하는 포스팅을 작성한다. 오늘은 아마도 마무리하는 글에 걸맞게 실무적으로 유용한 명령들이 될 것이다.

    (더 보기…)
  • wp-cli 사용하기 #2

    지난 포스트에 이어 wp cli 사용에 대해 계속 포스팅한다. 이 멋진 툴을 소개하려니 신난다. 한번에 좌르륵 풀어내기보다는 아껴서 조금씩조금씩 이야기하고 싶다. 자, 우선 무엇부터 시작할까?

    (더 보기…)
  • wp-cli 사용하기 #1

    의식의 흐름대로 흘러가는 1일 1워프 중이다. 적당히, 진짜 적당껏 분량 조절해서 하루에 하나씩 원하는 내용을 적는 중이다.

    오늘은 드디어 wp-cli의 이야기를 하게 된다. 워드프레스 개발자로서 반드시 숙지해야 할 녀석, 그리고 할 이야기가 무지무지 많은 녀석이다.

    (더 보기…)
  • 워드프레스 플러그인/테마 올바르게 번역하기

    잘못된 방법

    예전에 워드프레스 플러그인 만들기라는 문서를 작성한 적이 있다. 꽤 오래된 문서인데 (벌써 햇수로 6년 되었다!), 워드프레스 API는 여기서 그렇게 변경된 건 없는 것 같다.

    이 문서는 귀찮아서 업데이트하지 않고 있는데, 여기서의 텍스트 번역 부분은 그 당시 워드프레스 환경 및 일반적인 PHP 애플리케이션에 대해서는 맞다. 그러나 더이상 이 방법이 올바르다고 보기 어렵다.

    왜냐면 PoEdit을 이용한 소스 검색은 플러그인/테마의 헤더까지 번역문을 생성하지 않기 때문이다.

    올바른 방법

    플러그인 목록에 플러그인 제목과 나머지 헤더 내용까지 정확하게 번역하려면 wp-cli를 사용하는 것이 좋다. 이 앱에 대해서는 따로 소개하는 포스팅을 작성할 생각인데, 오늘은 맛보기로 미리 언급하기로 하자. 🙂

    wp cli 에는 i18n 명령이 있다. i18n은 ‘internationalization’을 간단히 줄여 쓸 때 자주 사용한다. 욕 아니다. i와 n 사이에 정확히 18글자가 있기 때문이다. 굳이 번역하면 ‘국제화’ 정도?

    사족으로, 이에 반대되는 개념이 지역화, 즉 ‘localization’ 인데 이것도 쓰기 어렵다고 ‘l10n’이라고 쓴다.

    i18n 명령의 서브 명령어로 ‘make-pot’과 ‘make-json’ 둘이 있다.

    make-json블록 에디터가 등장한 이후 자바스크립트에서 보다 편리하게 번역문을 처리하기 위한 새 방법을 지원하는 명령어고, 오늘 포스팅의 범위를 살짝 벗어난다.

    그럼 make-pot을 살펴보자. foo라는 플러그인을 예시로 레시피를 만들어 보자. 참고로 도메인은 bar라고 가정하자. 즉 소스 코드에서 __( 'Hello, World!', 'bar' ); 처럼 번역 텍스트를 작성했다는 뜻이다.

    cd <wordpress_path>/wp-content/plugins/foo
    mkdir languages # 디렉토리가 만들어지지 않았다면.
    wp-cli i18n make-pot . ./languages/bar.pot --domain=barCode language: Bash (bash)

    wp-cli로 번역 텍스트를 추출하면 기특하게 헤더 텍스트까지 알아서 잘 고려한다. 게다가 커맨드라인 방식이라 스크립트 처리하기 용이하다.

    이후 PoEdit을 이용해 번역문을 만든다. 만약 한국어로 번역했다면, 번역 파일의 이름은 bar-ko_KR.po 가 된다.

    기타: XDebug 사용시 트러블슈팅

    아마 xdebug를 사용하면 wp-cli로 pot 파일 생성시 ‘Maximum function nesting level of …’ 같은 에러를 만날 것이다. 이것은 xdebug가 디버깅을 위해 함수 호출 레벨을 낮춰 두기 때문이다. 아마도 소스 코드에서 번역문을 스캔할 때 꽤 많은 함수 중첩이 필요한가 보다.

    에러가 발생한다면 아래와 같은 명령어를 사용해 보자.

    php -d xdebug.max_nesting_level=512 $(which wp-cli) i18n [이후 동일]Code language: Bash (bash)

    참고로 아래처럼 번역에 불필요한 모듈까지 제거하면 속도 향상이 있다고 한다.

    php -n -dextension=phar.so \
        -dextension=json.so \
        -dextension=mbstring.so \
        -d xdebug.max_nesting_level=512 \
        $(which wp-cli) i18n (이후 동일)Code language: JavaScript (javascript)

    출처: Invoking wp i18n make-pot fails when Xdebug is enabled

  • 플러그인 헤더 보충 설명

    플러그인에는 플러그인 헤더가 반드시 필요하다. Header Requirement 코덱스에도 잘 나와 있지만, 몇가지 보충 설명을 더하고자 한다.

    플러그인 헤더를 작성하면 몇몇 내용은 플러그인 목록 정보에 반영된다. 한편 몇몇 내용은 플러그인 활성화 때 플러그인이 정상적으로 동작하는 환경인지 점검하기 위한 용도로 사용되기도 한다.

    목록 정보에 반영되는 필드들

    • Plugin Name: 플러그인 필수 헤더. 플러그인의 제목으로 사용.
    • Plugin URI: 기재하면 ‘플러그인 사이트 방문’이라고 나온다.
    • Description: 제목 옆에 플러그인 설명란으로 사용.
    • Version: 버전 정보로 표시.
    • Author: 작성자 정보로 표시.
    • Author URI: 기재하면 작성자 이름이 하이퍼링크로 변경. 클릭하면 해당 주소로 이동.

    플러그인 활성화시 영향을 주는 필드들

    • Requires at least: 플러그인이 요구하는 최소 워드프레스 버전이다. 만약 플러그인에서 사용하는 함수들을 워드프레스가 충분히 지원하는지 안전하게 확인하기 위한 용도로 사용된다. 만약 플러그인이 설치된 워드프레스가 이 버전보다 낮다면 활성화되지 않는다. 잘못하면 사이트 전체가 멈추는 불상사가 생길 수도 있기 때문이다.
    • Requires PHP: 플러그인이 요구하는 최소 PHP 버전이다. 마찬가지로 활성화시 PHP 버전을 체크하여 서버의 PHP 버전이 이 값보다 낮다면 플러그인은 활성화되지 않는다. ‘Requires at least’ 필드와 마찬가지로 오작동하면 사이트 전체를 멈출 수도 있기 때문이다.

    다국어 지원에 영향을 주는 필드들

    • Text Domain: 플러그인이 사용하는 텍스트도메인을 정확히 기재한다. 다국어 파일이 제대로 만들어졌다면 플러그인이 해당 언어로 표시된다. 위 그림에서도 ‘나란 옵션 편집기’나 ‘아키스밋’이나 헤더는 영어로 작성되었지만, 한국어 번역 파일이 존재하기 때문에 해당 헤더 필드가 번역되어 출력된다.
    • Domain Path: 플러그인의 번역 파일을 정확히 찾기 위해 도움을 주는 필드이다.

    다음에는 플러그인 목록 표시에 잘 반영되는 정확히 번역 파일 제작 방법에 대해 포스팅한다.

  • wp-util #2: wp.ajax

    지난 포스트에 이어 이번에는 wp.ajax 에 대해 포스팅한다. wp.ajax에 대해 소개하고 wp.ajax와 wp.template을 활용한 초간단 플러그인을 같이 제작해 본다.

    (더 보기…)
  • wp-util #1: wp.template

    오늘은 wp-util 스크립트를 소개하고자 한다. 경로는 /wp-includes/js/wp-util.js 이고, 이 스크립트 안에는 두가지 도구가 있는데, 하나는 wp.template, 나머지 하나는 wp.ajax이다. 간단하게 포스팅하는 것이 1일 1워프의 주제인데, 오늘 하루에 두가지를 다 포스팅하기는 내가 너무 힘들고 분량도 아까우므로 🙂 오늘은 그중 하나인 wp.template 만 알아보도록 하자.

    (더 보기…)
  • 액션/필터 레퍼런스

    코어 동작 어딘가에 적절히 콜백을 덧대 자신이 원하는 동작을 만들어내는 것, 이것이 플러그인 개발의 핵심이 아닐까 한다. 그러려면 코어가 어떤 흐름으로 동작하는지, 어떤 액션과 필터를 제공하는지 알아두는 것은 자명하다.

    그런 흐름을 잘 정리해 둔 문서가 바로 이 액션 레퍼런스필터 레퍼런스이다. 모든 필터와 액션을 담은 것은 아니겠지만, 리퀘스트를 받아 리스폰스를 내기까지의 순서를 따라 잘 나열되어 있다. 가장 흔히 사용되는 대표적인 필터와 액션 흐름을 살펴볼 수 있는 좋은 문서이다.

    프론트 기준으로 코어는 아주 대략적으로 이런 흐름으로 진행된다. 이 흐름을 생각하면서 훅을 훑어보면 코어를 이해하는데 많은 도움이 될 것이다.

    • 설정 파일 로드, 필수 파일 로드, 데이터베이스 설정.
    • MU 플러그인 로드.
    • 플러그인 로드.
    • 테마 로드.
    • 로그인된 사용자 설정.
    • 프론트의 주소에 따라 메인 쿼리 준비.
    • HTTP 헤더 전송.
    • 메인 쿼리 – 데이터베이스 쿼리.
    • 메인 쿼리의 종류에 따라 어떤 프론트 템플릿을 불러올지 결정.
    • 템플릿 인클루드.
      • 템플릿 헤더 출력.
      • 템플릿 본문과 설정에 따라 메뉴, 사이드바 출력.
      • 템플릿 푸터 출력.
    • 어드민 바 출력.
    • 종료.

    이 대략적인 흐름이 중요한 이유가 있다. 이 흐름을 모르면 도대체 어떤 때 어떤 동작을 넣어야 하는지 이해하기 어려울 뿐만 아니라 원하는 동작을 제때 코어에 전달하지 못할 수도 있기 때문이다. add_action을 넣는 시점은 do_action이 일어나기 이전에 이뤄져야 한다. 예를 들어 푸터 출력 진행중에 ‘plugins_loaded’ 액션을 넣어도 절대 동작하지 않는다. 왜냐면 ‘plugins_loaded’ 액션은 그 이전에 끝났기 때문이다. 이런 워드프레스 동작 라이프사이클은 알아둘수록 도움이 된다.

  • dashicons

    워드프레스 대시보드(또는 어디서든)에서 사용되는 아이콘 모음이다. 웹사이트에서 간편히 전체 목록을 확인할 수 있다.

    개발시 관리자 화면의 메뉴 아이콘을 꾸밀 때 특히 유용하다. 기본 아이콘인 톱니바퀴나 핀 말고 다양한 아이콘으로 만들어 보자.

    목록에서 원하는 아이콘을 클릭하면 아이콘 이름, HTML 코드나 CSS 스타일이 적절히 출력된다. 커스텀 포스트나 메뉴를 삽입할 때는 아이콘 이름을 쓰고, 나머지 경우에서는 적당히 HTML 태그나 CSS 스타일 요소 등을 사용하면 된다.

    예를 들어, 아래 커피 아이콘의 이름은 ‘dashicon-coffee’이다.

    이 아이콘을 커스텀 포스트의 메뉴 아이콘으로 쓰려면,

    <?php
    register_post_type(
        'foo_type',
        array(
            ....
            'menu_icon' => 'dashicons-coffee', // 이렇게!
        )
    );Code language: HTML, XML (xml)

    커스텀 페이지의 메뉴 아이콘으로 쓴다면,

    <?php
    add_menu_page(
        'Page Title',
        'Menu Title',
        'manage_options',
        'callback_function',
        'dashicons-coffee' // 이렇게!
    );Code language: HTML, XML (xml)

    이렇게 사용 가능하다.

  • wp_enqueue_script

    wp_enqueue_script() 함수는 직접적으로 HTML 코드에 스크립트를 조율해야 하는 과정을 없애준다. 스크립트간 의존성도 해결해주고, 캐시 문제도 해결해 준다. “JavaScript와 CSS를 삽입하는 과정을 명확히 알아두자.” 같은 긴 포스트를 작성하고는 싶지만, 글이 너무 길어지니 생략한다.

    그보다는 문서 중 여러 JS 라이브러리의 핸들을 문서화한 부분을 오늘 포스트의 키 포인트로 전달하고 싶다. 워드프레스가 사용한 여러 유용한 라이브러리를 재활용하는 측면에서 꽤 쓸만하다. 한번쯤 꼭 읽어보고 개발할 때 활용하도록 하자.

  • wp-config.php 설정 숙지하기

    wp-config.php 수정하기 문서.

    여기 내용들은 완전히까지는 아니지만 그래도 매우 잘 알아두어야 할 사항들이다. 어정쩡하게 알아두지 말고 한 번쯤 꼭 숙독해 두어야 한다.

    (더 보기…)
  • 플러그인 핸드북

    자 간단하게 시작하자, 그리고 꾸준하게 가 보자. 그러려면 하찮게 가자.

    (더 보기…)
  • front-page.php를 쓰지 말아야 할 이유

    얼마전 워드프레스 기반의 사이트 하나를 제작하였다. 그러나 워드프레스의 다양한 콘텐츠 기능을 활용하기 보다는 포스트의 아카이브/싱글에만 치우쳤고, 기존 테마들로는 구현하기 어려운 요소들이 너무 많아 아예 밑바닥부터 테마를 만들기로 결정했다. 이런 사이트들은 기존 테마를 억지로 비틀어 맞추는 것보다 처음부터 테마를 만드는 것이 훨씬 만들기되 쉽고 결과물도 좋다.

    보통 대문 페이지, 워드프레스에서는 프론트 페이지라고 부르는데, 방문자들이 보통 주소만 치고 들어올 때 보게 되는 대표 페이지이자 사이트의 얼굴이기 때문에 가장 신경을 많이 쓰는 페이지라고 할 수 있겠다. 이 페이지를 어떻게 만들까 생각했었는데, 별 신경 안 쓰고 테마의 front-page.php를 활용해 제작하기로 결정했다.

    그런데 나중에 만들고 보니 그것은 썩 좋지 않은 결정이었던 것 같다. 이 포스트에서는 그것이 왜 실수인지, 왜 쓰지 말아야 하는지에 대해 적고자 한다. 이렇게 구구절절히 적었으니 테마 제작시 같은 실수를 반복하지 않기를 바란다.

    (더 보기…)
  • 제발 맨 아래 텀만 찍어라

    ‘개발 레시피’ 텀도 찍을까 말까?

    카테고리 찍을 때 고민될 것이다. 맨 아래 텀만 찍을 것인가, 아래 텀과 같이 상위 텀도 찍어야 할 것인가? 상위 텀을 안 찍으면 상위 텀에 포함 안되는 것 아닐까 고민한 적 있으신지?

    보통 카테고리 같은 위계적인 택소노미에 대해 쿼리할 때 텀은 기본적으로 그 부모 위치의 텀은 기본적으로 모두 고려하여 작성이 되고, 하위 텀도 마찬가지다. 하위 텀은 프로그래머의 필요에 따라 포함시키지 않는 경우도 있지만 기본 동작은 포함되는 것이다.

    그러니까 맨 마지막 텀만 찍어라. 나중에 카테고리가 확장되어서 중간에 찍힐 수는 있겠지만, 현재 가장 말단에 위치한 텀만 찍으면 알아서 그 상위 텀에 포함된다. 괜히 중간 텀까지 찍어 놓으면 불필요한 정보만 더 쌓일 뿐이다.

  • 같은 옵션에 경쟁을 붙이면 어떻게 될까?

    워드프레스에서 옵션 테이블은 매우 자주 이용하는 테이블입니다. 여기에 사이트 전체에 빈번하게 사용되는 값들이 저장되어 있습니다. 코어, 테마, 플러그인 모두 상당히 이 옵션 테이블에 의존하고 있습니다. 때로는 너무 옵션 테이블에 의존해서 상당히 퍼포먼스가 떨어질 때도 있긴 하지요. 이 포스트에서는 그 퍼포먼스의 문제는 논외로 하고, 이 옵션 테이블의 업데이트를 할 때 알아두면 좋을 내용을 적어 보도록 하겠습니다.

    (더 보기…)

    페이지: 1 2 3 4 5

  • 아파치 워드프레스 관리자 IP 접속 제한

    주로 보안 제약이 강한 대기업 블로그에서 주로 요구하는 사항인데, 관리자나 로그인 페이지의 접근을 IP 대역으로 막는다.

    주의할 점은 관리자 페이지를 막아도 admin-ajax.php, admin-post.php 의 접근은 열어 두어야 한다는 거다. 그것까지 다 막으면 워드프레스의 일반적인 폼 제출과 AJAX 요청까지 다 틀어막혀 사이트 동작이 되지 않을 수 있다.

    아래 코드를 참고하여 아파치 설정에 추가한다. LocationMatch 지시자는 .htaccess 에 넣을 수 없다는 것에 유의한다. 그리고 .htacess 파일에 넣지 못하고 일반 설정 파일에 삽입하니, 수정 후 서버 재시작을 꼭 해주는 것을 잊지 말자.

    <LocationMatch "wp-admin/(?!admin-ajax|admin-post).*\.php$|wp-signup\.php$|wp-login\.php$">
    Require all denied
    Require ip 127.0.0.1
    </LocationMatch>
    # vim: syntax=apache ts=4 sw=4 sts=4 sr noet
  • 죽고 싶지만 떡볶이는 먹고 싶어 감상

    사실 나는 독서를 잘 안한다. 책 읽는 습관을 들이지 못했다. 집에 있으면 누워 있기만 했고, 여유 있는 시간에는 게임, 만화, 유튜브 시청을 더 좋아한다.

    그런데 요즘은 좀 달라졌다. 게임은 시들해졌고, 만화는 유치해졌다. 유튜브 동영상은 맨날 그나물에 그 밥이었다. 깊은 맛이 부족했다.

    외롭다는 감정이 좀 고통스럽게 느껴졌다. 사람을 만나고 싶은데, 이야기하고, 듣고 싶고, 교류하고 싶은데 그게 잘 안된다. 내 성격 자체가 그렇기도 하고, 시국이 시국이기도 하고…

    문득 에세이가 읽고 싶어졌다. 사람의 이야기를 직접 듣기 어렵다면, 책으로부터 잘 정돈된 이야기를 읽는 것으로 대체할 수 있지 않을까 생각해 봤다. 우선 나는 되게 외로우니, 외롭고 우울한 사람의 이야기부터 들어보면 어떨까 하는 생각이 들어 이 책, “죽고 싶지만 떡볶이는 먹고 싶어”를 읽게 되었다. 마침 요즘 나도 떡볶이가 너무 좋아져서 동질감도 들고, 책이 작고 가벼워 지하철에서 들고 읽기 딱 좋다고 생각했기 때문이다.

    아직 책 읽는 습관이 없는 나는 이 얇은 책도 술술 읽어 내려가기 어려웠다. 매일매일 유튜브나 인터넷 커뮤니티, 소셜미디어의 유혹에서, 아침 출근의 정신없음에서 책이 큰 비중을 차지하기는 어려웠다. 하루 정말 조금씩 책을 읽었다. 부담은 전혀 갖지 않고 그냥 책을 펼쳐 몇 페이지를 본다는 것만으로 의미를 가지려 했다.

    처음엔 정신과 상담을 묘사한 것을 읽어간 것만으로 내가 같이 상담을 받은 느낌이 들었다. 나도 필자 같이 우울함, 외로움으로 괴로울 때가 많은데, 책에 적인 솔직한 이야기를 읽으며 나도 내 맘을 편히 하는데 꽤 도움이 되었다고 생각한다. 그 점은 참 좋게 생각한다.

    하지만 책 끝까지 계속 그런 상담으로 채워지니, 가면 갈수록 솔직히 좀 지루해진다고 생각했다. 필자의 낮은 자존감, 그거 뭐 내가 계속 봐서 뭐해? 이런 생각이 들더라고. 내가 나쁜 건가? 끝까지 보기 싫어 마지막 몇 페이지를 남기고 읽기를 포기했다. 그렇지 않나? 누군가 대화를 하는데 계속 우울한 이야기, 낮은 자존감 이야기만 계속하면 금새 대화하기 싫지 않은가? 알았어 알았어, 작가님. 알겠어요. 나도 우울할 때가 많고, 작가님의 우울한 이야기가 처음에는 도움이 되었어요. 하지만 책 끝날 때까지 이러면 나도 힘들어요.

    내가 휴대폰을 계속 만지작거린다는 사실을 깨달았다. 시대가 완전히 변한 것 같다. 화장실을 갈 때도 휴대폰을 가져가지만, 책을 가져가지는 않는다. 그래, 밀리의 서재를 이용하자. 또 다른 사람의 에세이를 보자.

  • 이번 번역은 정말 아쉽다

    이번 워드프레스 한글 번역을 누가 했는지 물어보고 싶다.

    업데이트를 ‘업대이트’, 페이지를 ‘패이지’라고 한다.

    번역에서 % 서식 표시 미스로 인해 PHP 7.4이하에서는 경고, 8.0부터는 무려 에러를 낸다.

    PHP7.4에서는 경고가 발생한다.
    PHP8.0은 실행을 멈춘다.
    한국어 번역 부분에서 100%%로 적어야 하는데, 실수했다. sprintf 서식 문자열을 모르는 사람이 저지른 실수로 보인다.

    다만 ‘테마 디자인’을 ‘외관’으로 번역한 건 좀 맘에 든다.