상현에 하루하루
All 개발자의 하루

roots/sage10 커스텀 피드 (템플릿)

( 업데이트: )

sage10에서 custom feed를 만들기 매우 까다로웠다. Best Practice가 없어기 때문에 직접 생각해서 구성할 수 밖에 없었다.

add_feed의 템플릿을 sage 템플릿으로 사용해보기

커스텀 피드를 만들려면

add_action('init', 'customRSS');
function customRSS(){
        add_feed('feedname', 'customRSSFunc');
}
function customRSSFunc(){
        get_template_part('rss', 'feedname');
}

위와 같이 자식 테마 or 테마 functions.php에서 액션을 등록해서 사용해야하는데 여기서 콜백 함수에서 sage에서 만든 템플릿을 사용하게 하면 될꺼라 생각했다.

/**
 * Custom RSS Page
 *
 * @author       Hansanghyeon
 * @copyright    Hansanghyeon <999@hyeon.pro>
 **/

use function Roots\view;

add_action('init', function () {
  add_feed('popularity_post', function () {
    echo view('template-rss')->render();
    return view('template-rss')->render();
  });
});

위와 같이 설정해서 /?feed=popularity_post 들어가면 해당 템플릿이 적용되지 않는 것을 볼 수 있었다.

엉 뚱하게 다운로드가 뜬다. 아마도 헤더 설정이 안되서 그냥 다운로드 하는 것같다.

차근찬근 sage 템플릿을 사용하지 않고 구성

기본 커스텀 피드를 만든다

<?php
add_action('init', 'customRSS');
function customRSS(){
        add_feed('feedname', 'customRSSFunc');
}
function customRSSFunc(){
        get_template_part('rss', 'feedname');
}

위 처럼 구성하면

  • wp-content/themes/child/rss-feedname.php
  • wp-content/themes/parent/rss-feedname.php
  • wp-content/themes/child/rss.php
  • wp-content/themes/parent/rss-feedname.php
    위와 같이 feed template가 지정된다.

구성한 피드 이름으로 설정하는 것이 가장 좋다.

<?php
/**
 * Template Name: Custom RSS Template - Feedname
 */
$postCount = 5; // The number of posts to show in the feed
$posts = query_posts('showposts=' . $postCount);
header('Content-Type: '.feed_content_type('rss-http').'; charset='.get_option('blog_charset'), true);
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
?>
<rss version="2.0"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:wfw="http://wellformedweb.org/CommentAPI/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
        <?php do_action('rss2_ns'); ?>>
<channel>
        <title><?php bloginfo_rss('name'); ?> - Feed</title>
        <atom:link href="<?php self_link(); ?>" rel="self" type="application/rss+xml" />
        <link><?php bloginfo_rss('url') ?></link>
        <description><?php bloginfo_rss('description') ?></description>
        <lastBuildDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false); ?></lastBuildDate>
        <language><?php echo get_option('rss_language'); ?></language>
        <sy:updatePeriod><?php echo apply_filters( 'rss_update_period', 'hourly' ); ?></sy:updatePeriod>
        <sy:updateFrequency><?php echo apply_filters( 'rss_update_frequency', '1' ); ?></sy:updateFrequency>
        <?php do_action('rss2_head'); ?>
        <?php while(have_posts()) : the_post(); ?>
                <item>
                        <title><?php the_title_rss(); ?></title>
                        <link><?php the_permalink_rss(); ?></link>
                        <pubDate><?php echo mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false); ?></pubDate>
                        <dc:creator><?php the_author(); ?></dc:creator>
                        <guid isPermaLink="false"><?php the_guid(); ?></guid>
                        <description><![CDATA[<?php the_excerpt_rss() ?>]]></description>
                        <content:encoded><![CDATA[<?php the_excerpt_rss() ?>]]></content:encoded>
                        <?php rss_enclosure(); ?>
                        <?php do_action('rss2_item'); ?>
                </item>
        <?php endwhile; ?>
</channel>
</rss>

위와 같이 RSS 피드를 생성한다.

피드 템플릿 응용 sage 템플릿 적용하기

피드 템플릿에서 템플릿을 사용하기 위해서

<?php
$postCount = 5; // The number of posts to show in the feed
$posts = query_posts('showposts=' . $postCount);
header('Content-Type: '.feed_content_type('rss-http').'; charset='.get_option('blog_charset'), true);
echo '<?xml version="1.0" encoding="'.get_option('blog_charset').'"?'.'>';
?>
<?php echo \Roots\view('rss.popularity_post')->render(); ?>

핵심은 \Roots\view('rss.popularity_post')->render();를 통해서 sage 템플릿을 가져다 사용하는 것으로 템플릿 적용

sage 피드 컴포저

<?php

namespace App\View\Composers;

use Roots\Acorn\View\Composer;
use WP_Query;

class RSS extends Composer
{
    /**
     * List of views served by this composer.
     *
     * @var array
     */
    protected static $views = [
        'rss.popularity_post',
    ];

    /**
     * Data to be passed to view before rendering, but after merging.
     *
     * @return array
     */
    public function override()
    {
        return [
          'posts' => $this->getPost(),
        ];
    }

    public function getPost()
    {
      $posts = get_field('main-popularity_post', 'option');
      $ids = [];
      foreach ($posts as $post) {
        $ids[] = $post->ID;
      }

      return new WP_Query([
        'post_type' => 'any',
        'post__in' => $ids
      ]);
    }
}

핃자는 ACF 커스텀필드에 등록된 포스트들을 feed에 만드는 작업을 하였다.

sage 피드 템플릿

<rss version="2.0"
        xmlns:content="http://purl.org/rss/1.0/modules/content/"
        xmlns:wfw="http://wellformedweb.org/CommentAPI/"
        xmlns:dc="http://purl.org/dc/elements/1.1/"
        xmlns:atom="http://www.w3.org/2005/Atom"
        xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
        xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
        {!! do_action('rss2_ns') !!}
>
<channel>
        <title>{!! bloginfo_rss('name') !!} - Feed</title>
        <atom:link href="{!! self_link() !!}" rel="self" type="application/rss+xml" />
        <link>{!! bloginfo_rss('url') !!}</link>
        <description>{!! bloginfo_rss('description') !!}</description>
        <lastBuildDate>{!! mysql2date('D, d M Y H:i:s +0000', get_lastpostmodified('GMT'), false) !!}</lastBuildDate>
        <language>{!! get_option('rss_language') !!}</language>
        <sy:updatePeriod>{!! apply_filters( 'rss_update_period', 'hourly' ) !!}</sy:updatePeriod>
        <sy:updateFrequency>{!! apply_filters( 'rss_update_frequency', '1' ) !!}</sy:updateFrequency>
        {!! do_action('rss2_head') !!}
        @while($posts->have_posts()) @php($posts->the_post())
                <item>
                        <title>{!! the_title_rss() !!}</title>
                        <link>{!! the_permalink_rss() !!}</link>
                        <pubDate>{!! mysql2date('D, d M Y H:i:s +0000', get_post_time('Y-m-d H:i:s', true), false) !!}</pubDate>
                        <dc:creator>{!! the_author() !!}</dc:creator>
                        <guid isPermaLink="false">{!! the_guid() !!}</guid>
                        <description><![CDATA[{!! the_excerpt_rss() !!}]]></description>
                        <content:encoded><![CDATA[{!! the_excerpt_rss() !!}]]></content:encoded>
                        {!! rss_enclosure() !!}
                        {!! do_action('rss2_item') !!}
                </item>
        @endwhile
</channel>
</rss>