[워드프레스] 액션과 필터의 차이점

Last Updated: 2016년 08월 02일 2개 댓글

액션과 필터 후크

워드프레스에서는 액션(action)과 필터(filter) 후크를 사용하여 워드프레스 기능을 크게 확장할 수 있습니다. 프로그램을 배운 분들은 워드프레스에 접근할 때 소스 파일을 수정하려고 시도할 것입니다. (저도 처음 접할 때 소스를 많이 수정했습니다.)

하지만 이것은 바람직한 접근법이 아닙니다. 소스 수정을 최소화해야 하며, 특히 워드프레스든 플러그인이든 코어 파일은 수정하지 않아야 합니다. 코어 파일을 수정하는 경우 워드프레스나 플러그인이 업데이트될 때마다 수정을 반복해야 합니다. 하지만 시간이 지나면서 어디를 수정했는지 기억이 나지 않는 경우가 많아 낭패를 볼 수도 있을 것입니다. 후크를 통해 수정하거나 기능을 추가함으로써 이런 문제를 방지할 수 있습니다.

이전 글에서 add_filter에 대한 기본적인 내용을 다루었습니다. 시간이 될 때 액션과 필터를 함께 다루고 싶었지만 상황이 여의치 않네요.

액션과 필터 차이점

액션과 필터는 용도와 선언되어 사용되는 방식에 차이가 있습니다. 대강 정리하면 다음과 같습니다(참고).

액션(Action)

  • 무엇인가를 추가할 때 사용
  • 선언: add_action()
  • 사용: do_action()

필터(Filter)

  • 무엇인가를 변경해야 할 때 사용
  • 선언: add_filter()
  • 사용: apply_filters()

쉬운 이해를 이해 간단한 예를 들어보겠습니다.

워드프레스 액션 샘플

액션은 다음과 같은 형식으로 만들 수 있습니다.

add_action('my_action_hook_name', 'my_action_function_name', $priority);
function my_action_function_name() {
// 함수가 수행할 작업
}

여기에서 $priority는 옵션이고 기본값은 '10'입니다.

이 블로그에 많은 액션이 언급되고 있고 워드프레스를 사용하다 보면 다양한 액션과 필터 후크를 만나게 될 것입니다. 워드프레스에서 기본적으로 제공하는 후크가 있는가 하면 개별 플러그인에서도 제공하기도 합니다. 그리고 원하는 경우 사용자가 직접 만들어도 됩니다.

예를 들어, 워드프레스에서는 '쿼리 개체가 생성된 후에 실제 쿼리가 실행되기 전에 호출'하는 pre_get_posts 액션이 있습니다(WordPress Codex 페이지에 이 액션에 대해 설명되어 있습니다).

Codex 설명서를 보면 이 후크는 다음과 같이 사용할 수 있습니다.

<?php add_action( 'pre_get_posts', 'your_function_name' ); ?>

그리고 다양한 사용법이 나와 있습니다. 예를 들어 다음과 같은 예제를 살펴보면 액션이 구체적으로 어떻게 사용되는지를 이해하여 이를 응용할 수 있습니다.

function exclude_category( $query ) {
if ( $query->is_home() && $query->is_main_query() ) {
$query->set( 'cat', '-1,-1347' );
}
}
add_action( 'pre_get_posts', 'exclude_category' );

워드프레스에서 이 함수를 만나면 액션 목록에서 pre_get_posts를 찾습니다. pre_get_posts가 검색되면 $priority를 사용하여 언제 실행할지를 결정하려고 시도합니다. 숫자가 낮을수록 우선권이 주어집니다.

참고로 위의 코드에서 함수 exclude_category만 작성하고 실제 코드에서 사용하지 않을 않거나 액션 또는 필터로 후크를 해 주지 않으면 이 함수를 실행되지 않습니다. 위의 코드에서 후크를 해주지 않으려면 add_action( 'pre_get_posts', 'exclude_category' ); 파트만 주석 처리해주면 됩니다.

실행은 do_action('my_action_hook_name');을 통해 이루어집니다. do_action에 대한 워드프레스 설명서를 보면 do_action은 다음과 같은 형식으로 사용됩니다.

do_action ( string $tag,  $arg = '' );
  • $tag: (문자열) (필수) 실행할 액션 이름
  • $arg,...: (mixed) (옵션) 액션에 후크되는 함수로 전달되는 추가 인수. 기본적으로 비어 있습니다.

액션이 호출되면 해당 액션에 후크된 모든 함수가 실행됩니다.

References

필터에 대한 기본적인 사항은 이 글을 참고해보시기 바랍니다. 그리고 워드프레스 코덱스 페이지를 살펴보면 자세한 설명을 살펴볼 수 있습니다.

그리고 다음 글들도 참고해보시기 바랍니다.

 


2 개 댓글

Leave a Comment

  1. 글에서, '워드프레스에서 이 함수를 만나면 액션 목록에서 pre_get_posts를 찾습니다' 라는 문구가 있는데요. 함수를 만난다는게, do_action('pre_get_posts', 블라블라); 이 코드를 만난다는걸 말씀하시는거죠?

    응답
    • 안녕하세요?

      워드프레스에서 이 함수를 만나면 액션 목록에서 pre_get_posts를 찾습니다. pre_get_posts가 검색되면 $priority를 사용하여 언제 실행할지를 결정하려고 시도합니다. 숫자가 낮을수록 우선권이 주어집니다.

      액션은 함수 파일에 추가됩니다. 그러면 테마에서 함수 파일을 로드하면서 실행됩니다. 그런데 같은 액션에 대해 여러 개의 함수가 지정될 수 있습니다.

      위의 문구는 exclude_category 함수를 언제 실행할지에 대해 설명하는 것으로 이해하시면 좋을 듯 합니다.

      예를 들어,
      function search_filter($query) {
      if ( !is_admin() && $query->is_main_query() ) {
      if ($query->is_search) {
      $query->set('post_type', array( 'post', 'movie' ) );
      }
      }
      }

      add_action('pre_get_posts','search_filter');

      이 액션을 실행하면 검색 결과에 커스텀 포스트 타입을 포함하게 됩니다. function search_filter 함수도 pre_get_posts 액션이 걸려있습니다. 여기에서는 priority를 지정 안 해줬는데. 만약 먼저 실행해야 하는 함수가 있고 늦게 실행해야 하는 함수가 있다면 priority를 지정해주면 될 것입니다.

      예:
      add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );

      액션의 작동 원리는 아래를 참고하세요.

      function wpdocs_who_is_hook( $a, $b ) {
      echo '<code>';
      print_r( $a ); // `print_r` the array data inside the 1st argument
      echo '</code>';

      echo '<br />'.$b; // echo linebreak and value of 2nd argument
      }

      // then add it to the action hook, matching the defined number (2) of arguments in do_action
      // see [https://codex.wordpress.org/Function_Reference/add_action] in the Codex

      // add_action( $tag, $function_to_add, $priority, $accepted_args );
      add_action( 'wpdocs_i_am_hook', 'wpdocs_who_is_hook', 10, 2 );

      // Define the arguments for the action hook
      $a = array(
      'eye patch' => 'yes',
      'parrot' => true,
      'wooden leg' => 1
      );
      $b = __( 'And Hook said: "I ate ice cream with Peter Pan."', 'textdomain' );

      // Executes the action hook named 'i_am_hook'
      do_action( 'wpdocs_i_am_hook', $a, $b );

      응답