워드프레스 인기글 플러그인 WordPress Popular Posts에서 특정 글 제외하기

워드프레스 플러그인인 WordPress Popular Posts를 사용하면 사용자들이 자주 방문하는 게시글 목록을 표시할 수 있습니다. 이 플러그인에서는 전체 조회수, 일일 평균 조회수 또는 댓글 개수를 기준으로 인기 글을 표시할 수 있습니다.

이 플러그인을 사용하여 인기 글을 표시하는 경우, 특정 글을 제외시키고 싶은 경우가 있습니다. 이 글에서는 WordPress Popular Posts를 이용한 인기 글 리스트에서 특정 게시글들을 제외시키는 방법에 대하여 살펴보겠습니다.

워드프레스 인기글 플러그인 WordPress Popular Posts

워드프레스 사이트에 사용자들이 자주 방문하는 인기글들을 표시하고 싶나요? 그런 경우 먼저는 테마에서 이 기능을 제공하는지 체크해볼 수 있습니다. 예를 들어, 뉴스페이퍼 테마의 경우 인기 글을 표시하는 기능을 제공합니다.

하지만 대부분의 테마에서는 이 기능을 제공하지 않기 때문에 WordPress Popular Posts라는 워드프레스 플러그인을 사용할 수 있습니다.

워드프레스 인기글 플러그인 WordPress Popular Posts

이 플러그인은 2024년 10월 현재 20만 개가 넘는 사이트에 설치되어 사용되고 있고 워드프레스 5.7 버전 이상과 PHP 7.2 버전 이상에서 작동합니다.

이 무료 플러그인을 설치하고 활성화면 위젯이나 숏코드로 인기글 목록을 원하는 곳에 표시할 수 있습니다.

블록 편집기(블록 에디터)를 사용하는 경우 모양 » 위젯에서 WordPress Popular Posts 위젯을 선택할 수 있습니다.

위젯을 추가하면 표시할 글 개수, 정렬 기준, 시간 범위 (지난 24시간, 지난 7일, 지난 30일, 전체 시간, 사용자 정의), 글 유형 등 다양한 매개변수를 지정할 수 있습니다.

위젯을 사용할 수 없는 환경(클래픽 편집기 등)에서는 [wpp] 쇼트코드를 사용하여 인기 글 목록을 표시할 수 있습니다. 파라미터 없이 [wpp]를 사용하면 가장 많이 조회되는 게시글이 최대 10개까지 나열됩니다.

글 개수를 변경하거나 조회수(Views Count) 등을 숨기거나 표시하려는 경우 이 플러그인의 매뉴얼을 참고하여 숏코드를 만들 수 있습니다.

예를 들어, 지난 7일 간 가장 많은 조회수를 기록한 Top 5 글을 표시하고 싶다면 다음과 같은 단축 코드를 사용할 수 있습니다.

[wpp range='last7days' limit=5 stats_views=1 order_by='views']

지난 30일 간 가장 많은 댓글이 달린 글 Top 10을 표시하려면 다음과 같은 숏코드를 사용할 수 있습니다.

[wpp range='last30days' stats_comments=1 order_by='comments']

자세한 방법은 WordPress Popular Posts 공식 문서를 참고하시기 바랍니다.

WordPress Popular Posts에서 특정 글들을 제외하는 방법

특정 카테고리의 글들만 표시하고 싶거나 특정 글들을 제외시키고 싶은 경우에는 이 플러그인이 제공하는 필터(Filter)를 사용할 수 있습니다.

예를 들어, 특정 카테고리의 글들만 인기 글 목록에 표시하고 싶다면 다음과 같은 코드를 테마의 함수 파일에 추가합니다. (차일드 테마를 만들어 작업하세요.)

function wpp_display_only_one_category($terms) {
    return array_slice($terms, 0, 1);
}
add_filter('wpp_post_terms', 'wpp_display_only_one_category', 10, 1);

자세한 정보는 이 플러그인의 매뉴얼에서 wpp_post_terms 훅 부분을 참고해보시기 바랍니다.

코드를 자식 테마 함수 파일에 추가하려면 FTP에 접속할 수 있어야 합니다.

특정 글들을 제외하고 싶은 경우에는 이 플러그인이 제공하는 wpp_custom_html 필터를 사용할 수 있습니다.

다음과 같은 코드를 테마의 함수 파일에 추가하면 워드프레스 관리자 페이지에 제외할 글의 ID들을 입력하여 제외시킬 수 있습니다.

// 1. 관리자 설정 메뉴 추가
function wpp_exclude_posts_menu() {
	add_options_page(
		'Exclude Popular Posts', // 페이지 제목
		'Exclude Popular Posts', // 메뉴 제목
		'manage_options',        // 권한
		'exclude-popular-posts',  // 페이지 슬러그
		'wpp_exclude_posts_page'  // 콜백 함수 (페이지 표시)
	);
}
add_action('admin_menu', 'wpp_exclude_posts_menu');

// 2. 설정 페이지 HTML 출력
function wpp_exclude_posts_page() {
	?>
	<div class="wrap">
		<h1>Exclude Popular Posts</h1>
		<form method="post" action="options.php">
			<?php
			// 설정 필드 및 섹션 표시
			settings_fields('wpp_exclude_posts_group'); // 그룹 이름 확인
			do_settings_sections('exclude-popular-posts'); // 페이지 슬러그와 일치해야 함
			submit_button();
			?>
		</form>
	</div>
	<?php
}

// 3. 설정 초기화 및 필드 등록
function wpp_exclude_posts_settings() {
	// 설정 등록
	register_setting(
		'wpp_exclude_posts_group', // 설정 그룹
		'wpp_exclude_post_ids'     // 설정 옵션 이름
	);
	
	// 섹션 추가
	add_settings_section(
		'wpp_exclude_posts_section',  // 섹션 ID
		'Exclude Post IDs',           // 섹션 제목
		null,                         // 콜백 함수 (필요하지 않음)
		'exclude-popular-posts'        // 페이지 슬러그
	);
	
	// 설정 필드 추가
	add_settings_field(
		'wpp_exclude_post_ids_field', // 필드 ID
		'Post IDs to Exclude (comma separated)', // 필드 라벨
		'wpp_exclude_post_ids_field_callback',   // 콜백 함수 (필드 표시)
		'exclude-popular-posts',                 // 페이지 슬러그
		'wpp_exclude_posts_section'              // 섹션 ID
	);
}
add_action('admin_init', 'wpp_exclude_posts_settings');

// 4. 입력 필드 콜백
function wpp_exclude_post_ids_field_callback() {
	// 옵션 값 가져오기
	$exclude_post_ids = get_option('wpp_exclude_post_ids');
	// 입력 필드 출력
	echo '<input type="text" name="wpp_exclude_post_ids" value="' . esc_attr($exclude_post_ids) . '" class="regular-text">';
}

// 5. 인기 글 목록에서 제외할 글 ID 처리
function my_custom_popular_posts_html_list($popular_posts, $instance) {
	$excluded_posts_option = get_option('wpp_exclude_post_ids');
	$excluded_posts = !empty($excluded_posts_option) ? array_map('intval', explode(',', $excluded_posts_option)) : [];
	
	$output = '<ol class="wpp-list">';
	$displayed_posts = 0;
	$total_to_display = intval($instance['limit']); // 지정된 글 수를 정수로 처리
	$index = 0;
	
	while ($displayed_posts < $total_to_display && isset($popular_posts[$index])) {
		$popular_post = $popular_posts[$index];
		$index++;
		
		// 제외된 글인지 확인
		if (in_array(intval($popular_post->id), $excluded_posts)) {
			continue;
		}

		$stats = array();

		// 댓글 수 표시
		if ( $instance['stats_tag']['comment_count'] ) {
			$stats[] = '<span class="wpp-comments">' . sprintf(
				_n('1 comment', '%s comments', intval($popular_post->comment_count), 'wordpress-popular-posts'),
				number_format_i18n(intval($popular_post->comment_count))
			) . '</span>';
		}

		// 조회 수 표시
		if ( $instance['stats_tag']['views'] ) {
			if ($instance['order_by'] == 'avg') {
				$stats[] = '<span class="wpp-views">' . sprintf(
					_n('1 view per day', '%s views per day', intval($popular_post->pageviews), 'wordpress-popular-posts'),
					number_format_i18n(intval($popular_post->pageviews), 2)
				) . '</span>';
			} else {
				$stats[] = '<span class="wpp-views">' . sprintf(
					_n('1 view', '%s views', intval($popular_post->pageviews), 'wordpress-popular-posts'),
					number_format_i18n(intval($popular_post->pageviews))
				) . '</span>';
			}
		}

		// 작성자 정보 표시
		if ( $instance['stats_tag']['author'] ) {
			$author = esc_html(get_the_author_meta('display_name', intval($popular_post->uid)));
			$display_name = '<a href="' . esc_url(get_author_posts_url(intval($popular_post->uid))) . '">' . $author . '</a>';
			$stats[] = '<span class="wpp-author">' . sprintf(__('by %s', 'wordpress-popular-posts'), $display_name). '</span>';
		}

		// 날짜 표시
		if ( $instance['stats_tag']['date']['active'] ) {
			$date = date_i18n(esc_attr($instance['stats_tag']['date']['format']), strtotime($popular_post->date));
			$stats[] = '<span class="wpp-date">' . sprintf(__('posted on %s', 'wordpress-popular-posts'), $date) . '</span>';
		}

		// 카테고리 표시
		if ( $instance['stats_tag']['category'] ) {
			$post_cat = get_the_category(intval($popular_post->id));
			$post_cat = ( isset($post_cat[0]) )
			  ? '<a href="' . esc_url(get_category_link($post_cat[0]->term_id)) . '">' . esc_html($post_cat[0]->cat_name) . '</a>'
			  : '';
			if ( $post_cat != '' ) {
				$stats[] = '<span class="wpp-category">' . sprintf(__('under %s', 'wordpress-popular-posts'), $post_cat) . '</span>';
			}
		}

		// 통계 출력
		if ( ! empty($stats) ) {
			$stats = '<div class="wpp-stats">' . join(' | ', $stats) . '</div>';
		} else {
			$stats = null;
		}

		// 발췌문 표시
		$excerpt = '';
		if ( $instance['post-excerpt']['active'] ) {
			$excerpt = get_excerpt_by_id(intval($popular_post->id));
			if ( ! empty($excerpt) ) {
				$excerpt = '<div class="wpp-excerpt">' . esc_html($excerpt) . '</div>';
			}
		}
		
		// 출력에 추가
		$output .= "<li>";
		$output .= "<p class=\"entry-title\"><a href=\"" . esc_url(get_permalink(intval($popular_post->id))) . "\" title=\"" . esc_attr($popular_post->title) . "\">" . esc_html($popular_post->title) . "</a></p>";
		$output .= $stats;
		$output .= $excerpt;
		$output .= "</li>" . "\n";
		
		$displayed_posts++;
	}

	// 부족한 게시물을 채우기 위해 추가로 포스트를 가져오는 로직
	if ($displayed_posts < $total_to_display) {
		$args = array(
			'posts_per_page' => $total_to_display - $displayed_posts,
			'post__not_in' => $excluded_posts,
			'orderby' => 'date',
			'order' => 'DESC',
			'post_type' => 'post', // 특정 포스트 타입을 명시하여 보안 강화
			'post_status' => 'publish' // 공개된 글만 가져옴으로써 비공개 글 제외
		);
		$additional_posts = get_posts($args);
		
		foreach ($additional_posts as $post) {
			$output .= "<li>";
			$output .= "<p class=\"entry-title\"><a href=\"" . esc_url(get_permalink($post->ID)) . "\" title=\"" . esc_attr($post->post_title) . "\">" . esc_html($post->post_title) . "</a></p>";
			$output .= "</li>" . "\n";
		}
	}
	
	$output .= '</ol>';
	return $output;
}
add_filter('wpp_custom_html', 'my_custom_popular_posts_html_list', 10, 2);

차일드 테마에 코드를 추가하는 것에 어려움을 겪는 경우 플러그인으로 만들어 설치할 수도 있습니다. 상기 코드를 사용하여 플러그인을 만들어 보았습니다. 코드가 몇 줄 안되기 때문에 사이트 속도에는 거의 영향을 미치지 않을 것입니다. 다음 네이버 카페에서 다운로드하시기 바랍니다.

위의 코드를 추가하거나 플러그인을 설치하면 설정 » Exclude Popular Posts에서 제외할 글들을 포스트 ID로 등록하여 제외시킬 수 있습니다. 여러 개를 입력할 경우 콤마로 구분해 주세요.

글 ID(Post ID)를 확인하는 방법은 아래의 "글 ID 확인하기" 부분을 참고하세요.

다음 환경에서 잘 작동했습니다.

다른 환경에서도 잘 작동할 것으로 보이지만, 오류가 발생하는 경우 이 글이나 네이버 카페 글을 통해 알려주시면 코드를 수정할 수 있는 경우 수정하도록 하겠습니다.

보안 취약점도 존재하지 않도록 조치를 취했지만 코드 개선이 필요하다면 댓글을 통해 알려주시면 감사하겠습니다.

인기글 목록의 스타일은 CSS를 사용하여 원하는 대로 바꿀 수 있습니다.

썸네일(특성 이미지)을 표시하고 싶은 경우

만약 썸네일을 표시하고 싶다면 상기 코드에서 썸네일을 표시하는 코드를 추가할 수 있습니다. 예시:

// 썸네일 표시
$thumbnail = get_the_post_thumbnail($popular_post->id, 'thumbnail'); // 'thumbnail'은 이미지 사이즈. 필요에 따라 'medium', 'large' 등으로 변경 가능

$output .= "<li>";
// 썸네일 추가
if ($thumbnail) {
	$output .= "<div class='wpp-thumbnail'>" . $thumbnail . "</div>";
}
$output .= "<p class=\"entry-title\"><a href=\"" . esc_url(get_permalink(intval($popular_post->id))) . "\" title=\"" . esc_attr($popular_post->title) . "\">" . esc_html($popular_post->title) . "</a></p>";
$output .= $stats;
$output .= $excerpt;
$output .= "</li>" . "\n";

위의 코드를 적절히 응용하여 추가해보시기 바랍니다. 마찬가지로 CSS를 사용하여 레이아웃이나 스타일을 지정할 수 있습니다.

글 ID 확인하기

글 ID(포스트 ID)는 글 목록에서 해당 글 위에 마우스를 올려 쉽게 체크할 수 있습니다.

워드프레스 포스트 ID 확인하기

이 방법이 번거로운 경우 Show Pages IDs와 같은 플러그인을 설치할 수 있지만, 굳이 이 때문에 플러그인을 추가로 설치할 필요는 없지 않나 생각됩니다.

참고

댓글 남기기

댓글 남기기