워드프레스에서 커스텀 필터를 응용하는 예
참고 : https://codex.wordpress.org/Function_Reference/add_filter
개요
워드프레스의 플러그인 형태 중에 대표적인 것이 Action과 Filter인데 필터는 시스템에 의해서 생성된 화면 출력 데이터가 화면에 그대로 출력되기 전에 이용자(개발자)에 의해서 다시 변경될 수 있는 기회를 주는데 의미가 있다. 개발자가 정의한 커스텀 필터 후크에 함수를 등록하고 그 필터함수가 호출되는 적절한 시기를 결정하여 필터함수에 변경될 데이터를 전달해주는 절차를 자세한 코드를 통해 알아보고 테스트하려고 한다
테스트 환경
Windows 8
Autoset 9
WordPress 4.4
필터를 설정할 때 사용하는 함수들
add_filter()
지정된 필터 후크에 필터 함수를 등록함
add_filter( $tag, $function_to_add, $priority, $accepted_args );
- $tag : 필터 후크 이름
- $function_to_add : 필터 후크에 연결될 함수 이름
- $priority : 동일한 필터 후크에 여러개의 함수가 등록된 경우, 실행될 함수의 우선순위. 낮을수록 먼저 실행됨
- $accepted_args : 실행될 함수가 받아 들이는 아규먼트의 수. 워드프레스 1.5.1부터는 apply_filter()함수에서 전달한 아규먼트의 수만큼 받아들일 수 있음
- 리턴 값 : 필터 후크에 함수를 성공적으로 등록한 경우는 true, 아니면 false
apply_filters()
지정한 필터 후크에 등록된 필터 함수들을 호출함. 새로운 필터 후크를 생성하면서 해당 필터 후크에 등록된 필터함수를 호출함
apply_filters( $tag, $value, $var ... );
- $tag : 필터 후크 이름 (필수)
- $value : 필터함수에 전달되어 수정될 데이터 (필수). 필터함수는 이 값을 수정하여 리턴해야 함
- $var... : 다수개의 아규먼트가 필터 함수로 전달되지만 필터함수에서 변경할 수는 없고 필터함수는 이 값을 리턴하지는 않는다(옵션)
- 리턴 값 : 필터함수가 내용을 변경하여 리턴한 $value의 값. $value 의 자료형과 동일한 자료형이어야 한다
아래의 예에서 add_filter()를 통해 필터 함수가 3개의 아규먼트를 가져야 한다는 것을 선언하고 있다. 그러므로 필터함수는 3개의 파라미터 변수를 선언해야 한다. 그리고 필터함수를 호출하는 apply_filters()함수에서는 필터함수에게 3개의 아규먼트를 전달해야 한다
/**
* add_action(), add_filter() 함수는 워드프레스가 시작되어 플러그인 들이 등록될 때 자동으로 호출되며,
* 그 결과 특정 후크(Hook)에 함수가 등록(연결)되어 해당함수가 호출될 준비가 완료된다.
* 이후에 apply_filters()함수를 호출하면 필터 후크에 등록된 함수가 실행된다
**/
add_filter('img_caption_shortcode', 'my_img_caption_shortcode_filter',10,3);
/**
* Filter to replace the [caption] shortcode text with HTML5 compliant code
* @return text HTML content describing embedded figure
**/
function my_img_caption_shortcode_filter($val, $attr, $content = null)
{
extract(shortcode_atts(array(
'id' => '',
'align' => '',
'width' => '',
'caption' => ''
), $attr));
if ( 1 > (int) $width || empty($caption) )
return $val;
$capid = '';
if ( $id ) {
$id = esc_attr($id);
$capid = 'id="figcaption_'. $id . '" ';
$id = 'id="' . $id . '" aria-labelledby="figcaption_' . $id . '" ';
}
return '<figure ' . $id . 'class="wp-caption ' . esc_attr($align) . '" style="width: '
. (10 + (int) $width) . 'px">' . do_shortcode( $content ) . '<figcaption ' . $capid
. 'class="wp-caption-text">' . $caption . '</figcaption></figure>';
}
위의 필터함수가 실행되기 위해서는 다음과 같이 apply_filters() 함수를 호출해야 한다. 여기에서 전달한 3개의 값이 필터함수로 전달된다
// Allow plugins/themes to override the default caption template.
$output = apply_filters('img_caption_shortcode', '', $attr, $content);
if ( $output != '' )
return $output;
필터 응용 예제
아래의 코드는 페이지 하단에 페이지 네비게이션을 보여주는 플러그인(Shortcode)이다. 이 플러그인이 삽입된 템플릿 페이지에서는 다음과 같은 형태의 네비게이션이 보여지게 된다.
만약, 맨처음으로 이동( |< ), 맨 끝으로 이동( >| ) 아이콘을 이용자가 변경하여 사용할 수 있도록 하려면 이용자가 필터를 정의하여 변경하도록 하면 된다. 이용자가 정의한 필터함수가 실행되도록 하려면, apply_filters() 함수를 호출하여 그 리턴값을 화면에 출력하면 되므로 필터가 실행될 수 있는 플러그인을 만드는 것은 매우 간단한 일이다.
페이지 네비게이션 플러그인의 기본적인 코드(다른 필터를 호출하지 않도록 작성된 버전)
<?php /* Plugin Name: KCW Pagination Plugin Plugin URI: http://micropilot.tistory.com Description: 페이지 하단에 페이지 네비게이션 링크를 보여주는 플러그인 Shortcode [kcw_show_page_navi table='myguests' rows_per_screen='3' pages_per_screen='3' page_param_name='pg'] Version: 1.0 Author: Kim Chang Woon Author URI: http://micropilot.tistory.com */ // Pagination Start//////////////////////////////// // 화면의 페이지 하단에 페이지 네비게이션을 출력하는 함수 // Shortcode[kcw_show_page_navi table='myguests' pages_per_screen='5' rows_per_screen='3' page_param_name='pg'] add_shortcode('kcw_show_page_navi', 'kcw_show_page_navi'); function kcw_show_page_navi($atts) { set_navi_style(); $table = $atts['table']; $pages_per_screen = $atts['pages_per_screen']; $rows_per_screen = (int)$atts['rows_per_screen']; $page_param_name = $atts['page_param_name']; $cur_page = 1; if(isset($_GET[$page_param_name])){ $cur_page = $_GET[$page_param_name]; } global $wpdb; $total_rows = $wpdb->get_col("SELECT count(id) FROM $table"); $tmp = ((int)$total_rows[0]) / ((int)$rows_per_screen); $tmp += (((int)$total_rows[0]) % ((int)$rows_per_screen)) > 0 ? 1 : 0; $total_pages = (int)$tmp; // 현재 페이지($cur_page)는 몇번째 네비게이션 그룹에 속하나? $tmp = $cur_page / $pages_per_screen; $tmp += $cur_page % $pages_per_screen > 0 ? 1 : 0; $group = (int)$tmp; $pg_end = $group * $pages_per_screen; $pg_start = $pg_end - ($pages_per_screen-1); $pg_end = $pg_end > $total_pages ? $total_pages : $pg_end; //log_d('페이지네이션', "cur_page=$cur_page, pages_per_screen=$pages_per_screen, group=$group, total_rows=$total_rows[0], total_pages=$total_pages, offset=$offset, $pg_start~$pg_end"); echo "<hr>"; // 첫 페이지로 이동 링크(|<) echo "<span class=\"end_page\"><a href=".get_permalink()."?$page_param_name=1> |< </a></span>"; // 전 페이지 이동 링크(<<) if($pg_start > 1) { $prev_page = $pg_start-1; echo "<span class=\"next_page\"><a href=".get_permalink()."?$page_param_name=$prev_page> << </a></span>"; } // 페이지 번호 링크 for($i=$pg_start;$i<=$pg_end;$i++){ ?> <span class="page_num <?php echo $i==$cur_page ? 'cur_page':'';?>"> <a href="<?php echo get_permalink()."?$page_param_name=$i";?>"> <?php echo $i ?> </a> </span> <?php } // 다음 페이지 이동 링크(>>) if($pg_end < $total_pages){ $next_page = $pg_end+1; echo "<span class=\"next_page\"><a href=".get_permalink()."?$page_param_name=$next_page> >> </a></span>"; } // 마지막 페이지로 이동 링크(>|) echo "<span class=\"end_page\"><a href=".get_permalink()."?$page_param_name=$total_pages> >| </a></span>"; } // 프런트 엔드 스크립트가 필요하다면 아래처럼... add_action('wp_head', 'init'); function init(){ ?> <script> jQuery(function(){ //jQuery('span.cur_page').css('background-color', 'yellow'); }); </script> <?php } // 페이지 네비게이션 스타일 설정 function set_navi_style(){ ?> <style> span.page_num {border:1px solid gray; margin:5px; padding:5px;text-align:center;} span.next_page {border:1px solid gray; margin:5px; padding:5px;text-align:center; background-color:rgb(240,240,240);} span.end_page {border:1px solid gray; margin:5px; padding:5px;text-align:center; background-color:rgb(220,220,220);} span.cur_page {background-color:yellow;} </style> <?php } ?>
맨 처음으로 이동(|<), 맨 마지막으로 이동(>|) 아이콘을 변경할 수 있도록 필터를 사용하게 하려면 위의 코드에 아래처럼 두줄의 코드를 삽입하면 끝이다
........
............
// 첫 페이지로 이동 링크(|<)
$first_pg_icon = apply_filters('first_page_icon', '|<');
echo "<span class=\"end_page\"><a href=".get_permalink()."?$page_param_name=1> $first_pg_icon </a></span>";
<?php /* Plugin Name: KCW Pagination Icon Filter Plugin Plugin URI: http://micropilot.tistory.com Description: 페이지 네비게이션 플러그인의 처음으로, 마지막으로 아이콘을 변경하는 필터 플러그인 Version: 1.0 Author: Kim Chang Woon Author URI: http://micropilot.tistory.com */ // 필터 후크에 필터함수 등록 add_filter('first_page_icon', 'change_first_pg_icon'); function change_first_pg_icon($icon){ $icon = '|<<<'; return $icon; } // 필터 후크에 필터함수 등록 add_filter('last_page_icon', 'change_last_pg_icon'); function change_last_pg_icon($icon){ $icon = '>>>|'; return $icon; } ?>