본문 바로가기

WordPress/Custom Filter exmple

WordPress Custom Filter example

워드프레스에서 커스텀 필터를 응용하는 예


참고 : https://codex.wordpress.org/Function_Reference/add_filter


개요

워드프레스의 플러그인 형태 중에 대표적인 것이 ActionFilter인데 필터는 시스템에 의해서 생성된 화면 출력 데이터가 화면에 그대로 출력되기 전에 이용자(개발자)에 의해서 다시 변경될 수 있는 기회를 주는데 의미가 있다. 개발자가 정의한 커스텀 필터 후크에 함수를 등록하고 그 필터함수가 호출되는 적절한 시기를 결정하여 필터함수에 변경될 데이터를 전달해주는 절차를 자세한 코드를 통해 알아보고 테스트하려고 한다



테스트 환경

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> |&lt; </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> &lt;&lt; </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> &gt;&gt; </a></span>";
	}
	
	// 마지막 페이지로 이동 링크(>|)
	echo "<span class=\"end_page\"><a href=".get_permalink()."?$page_param_name=$total_pages> &gt;| </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', '|&lt;');

echo "<span class=\"end_page\"><a href=".get_permalink()."?$page_param_name=1> $first_pg_icon </a></span>";

........
...........
// 마지막 페이지로 이동 링크(>|)
$last_pg_icon = apply_filters('last_page_icon','&gt;|');
echo "<span class=\"end_page\"><a href=".get_permalink()."?$page_param_name=$total_pages> $last_pg_icon </a></span>";
  .........


위의 네비게이션 플러그인을 사용하는 이용자는 처음으로 이동, 마지막으로 이동 링크를 변경하여 사용하고자 한다면, 플러그인 파일을 생성하고 아래의 코드처럼 위에서 정의한 'first_page_icon', 'last_page_icon' 필터 후크에 필터함수를 등록해주면 된다
wp-content/plugins/my-plugin-test/kck-pagination-icon-change-filter.php
<?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 = '|&lt;&lt;&lt;';
	return $icon;
}

// 필터 후크에 필터함수 등록
add_filter('last_page_icon', 'change_last_pg_icon');
function change_last_pg_icon($icon){
	$icon = '&gt;&gt;&gt;|';
	return $icon;
}
?>