如何创建自己的简单 WordPress 播客插件

Avatar of Geoff Graham
Geoff Graham

DigitalOcean 为您的旅程的每个阶段提供云产品。 立即开始使用 200 美元的免费积分!

假设您计划开始播客。 您拥有录音设备、一个有趣的主题以及一个其他人想听的好声音。 您似乎正在顺利地填补着各处的耳机。

然后是托管播客的问题。 iTunes 需要 RSS Feed,以便它可以在您的剧集可用时将其分发给订阅者,但是您该怎么做呢? 好消息是,有许多方法可以托管播客。 例如,您可以使用托管服务,该服务通常会收取费用,并在一个整洁的地方为您提供存储和分发。 如果您使用 WordPress 并已经研究过播客,您可能已经看到所有可用的强大的播客插件。

在本篇文章中,我们将跳过这些选项,看看如何仅使用 WordPress 网站和两个附加文件来托管自己的播客。 具体来说,我们将

  • 设置一个新插件
  • 注册自定义 RSS Feed
  • 为我们的播客创建自定义帖子类型
  • 将自定义字段分配给我们的自定义帖子类型
  • 创建 RSS Feed 模板

目标不是过度思考。 如果您已经拥有 WordPress 网站,并且您只需要一个提交通往 iTunes 的 Feed,那么我们就是要做这件事。 让我们开始吧。

设置插件

创建插件是主题 `functions.php` 文件中编写代码的一个不错的替代方法。 除了保持主题功能的整洁和无杂乱外,它还将播客 Feed 功能保存在 `/wp-content/plugins/` 目录中,即使您更改主题,它也会保留在那里。

创建插件目录

首先。 让我们在 `/wp-content/plugins/` 目录中创建一个名为 `my-awesome-podcast` 的新文件夹。

创建插件

现在,让我们在刚创建的文件夹中创建一个新的 PHP 文件,并将其命名为 `my-awesome-podcast.php`。 这将是注册插件的主要文件,也是我们为播客编写功能的地方。

有了这个文件,我们将添加以下代码注释,告诉 WordPress 插件的名称、描述和版本。 我们还可以添加 其他信息,但这已经足够了。

/**
Plugin Name: My Awesome Podcast
Description: A really simple RSS feed and custom post type for a podcast
Version: 1.0
**/

// This is where we will start writing our plugin

注册 RSS Feed

接下来,我们需要注册一个新的 RSS Feed。 谢天谢地,WordPress API 有一个方便的 add_feed() 函数,我们可以将其挂钩以使其相对容易。

add_action('init', 'podcast_rss');
function podcast_rss(){
  add_feed('my-awesome-podcast', 'my_podcast_rss');
}

这里发生的事情是,我们定义了一个名为 `podcast_rss()` 的新函数,并扩展了 WordPress `add_feed()` 函数以创建一个名为“my_podcast_rss” 的新 RSS Feed,它将位于我们网站的 `/feed/my-awesome-podcast` 上。

注意: 您可以在此处将“my-awesome-podcast” 更改为您想要的任何内容。 这是 Feed 的 URL 标识符,因此它可以是您的播客标题或您喜欢的任何其他内容。

注册播客自定义帖子类型

创建 Feed 后,我们需要设置一个新的帖子类型,以便我们可以使用它来发布剧集的帖子。 因此,我们将创建一个名为“Podcast” 的全新帖子类型,而不是 WordPress 默认的“Post” 或“Page”。 WordPress Codex 对 如何创建自定义帖子类型 做了很好的解释,因此无需在此赘述。 甚至有一些插件可以做到这一点,如果您愿意的话,可以选择这样操作。 无论如何,假设我们没有插件的帮助,并在我们的文件中创建 Podcast 自定义帖子类型。

function custom_post_type() {

  $labels = array(
    'name'                => _x( 'Podcasts', 'Podcast General Name', 'text_domain' ),
    'singular_name'       => _x( 'Podcast', 'Course Singular Name', 'text_domain' ),
    'menu_name'           => __( 'Podcasts', 'text_domain' ),
    'parent_item_colon'   => __( 'Parent Podcast:', 'text_domain' ),
    'all_items'           => __( 'All Podcasts', 'text_domain' ),
    'view_item'           => __( 'View Podcast', 'text_domain' ),
    'add_new_item'        => __( 'Add New Podcast', 'text_domain' ),
    'add_new'             => __( 'Add New', 'text_domain' ),
    'edit_item'           => __( 'Edit Podcast', 'text_domain' ),
    'update_item'         => __( 'Update Podcast', 'text_domain' ),
    'search_items'        => __( 'Search Podcasts', 'text_domain' ),
    'not_found'           => __( 'Not found', 'text_domain' ),
    'not_found_in_trash'  => __( 'Not found in Trash', 'text_domain' ),
  );
  $args = array(
    'label'               => __( 'podcasts', 'text_domain' ),
    'description'         => __( 'Podcast Description', 'text_domain' ),
    'labels'              => $labels,
    'supports'            => array( 'title', 'editor', 'thumbnail' ),
    'taxonomies'          => array( 'category', 'post_tag' ),
    'hierarchical'        => false,
    'public'              => true,
    'show_ui'             => true,
    'show_in_menu'        => true,
    'show_in_nav_menus'   => true,
    'show_in_admin_bar'   => true,
    'menu_position'       => 5,
    'menu_icon'           => 'dashicons-format-audio',
    'can_export'          => true,
    'has_archive'         => true,
    'exclude_from_search' => false,
    'publicly_queryable'  => true,
    'capability_type'     => 'page'
  );
  register_post_type( 'podcasts', $args );
}

add_action( 'init', 'custom_post_type', 0 );

这段代码很多,但它只是注册名为 Podcast 的新帖子类型的配置。 它定义了 WordPress 仪表板中它的各种标签,并告诉 WordPress 如何处理它。 同样,如果您有兴趣,WordPress Codex 对这些内容进行了更详细的解释。

此时,我们可以进入 WordPress 管理员的插件部分,查看 **我的精彩播客** 是否已列为可用的插件。 继续并激活它。

为播客帖子创建自定义字段

WordPress 帖子开箱即用就能为我们做很多事情,但有时我们需要其他字段,以便我们可以发布特定内容。 在这种情况下,iTunes 对 RSS Feed 中需要提供哪些信息 有非常具体的格式要求。

通过额外的开发,有一种方法可以 将自定义字段添加到我们的自定义帖子类型 中,但我实际上更喜欢使用 Advanced Custom Fields 插件 来完成这类事情。 它使我们能够为添加的每个字段提供一个干净简洁的自定义 UI,而不是默认自定义字段提供的通用键值对 UI。

使用 Advanced Custom Fields,让我们设置一个名为 Podcast 的新字段组,将其分配给 Podcast 帖子类型,并创建以下字段

  • podcast_file: 使用“File” 字段类型,以便我们可以将播客文件直接上传到帖子中。 将字段设置为返回值为“File ID”,因为这将有助于我们稍后自动检测文件大小。
  • podcast_duration: 这是一个简单的文本字段,我们将使用它以 HH:MM:SS 格式发布剧集的长度。

注意: 虽然我在本示例中使用了“File” 字段类型,但理论上,如果您计划在服务器以外的其他地方托管播客文件(例如 Amazon S3),则可以使用文本字段,并将 URL 直接粘贴到其中。 但是,我们无法通过这种方式自动检测文件大小,尽管我们可以使用另一个文本字段来实现此目的。

创建 RSS 模板

到目前为止,我们已经做了很多。 最后要做的事情是创建用于显示播客帖子数据的模板。

Apple 概述了可接受的播客 RSS Feed 的规范,它非常具体。 使用该概述作为指南,让我们在插件文件夹中创建一个名为 `podcast-rss-template.php` 的文件。 顾名思义,对吧?

好消息是,我们的 RSS 模板在技术上与任何其他 WordPress 模板没有区别。 我们将查询我们的帖子,创建一个循环,并将我们的数据插入到需要的地方。

/** 
Template Name: Podcast RSS
**/

// Query the Podcast Custom Post Type and fetch the latest 100 posts
$args = array( 'post_type' => 'podcasts', 'posts_per_page' => 100 );
$loop = new WP_Query( $args );

/**
 * Get the current URL taking into account HTTPS and Port
 * @link https://css-tricks.cn/snippets/php/get-current-page-url/
 * @version Refactored by @AlexParraSilva
 */
function getCurrentUrl() {
    $url  = isset( $_SERVER['HTTPS'] ) && 'on' === $_SERVER['HTTPS'] ? 'https' : 'http';
    $url .= '://' . $_SERVER['SERVER_NAME'];
    $url .= in_array( $_SERVER['SERVER_PORT'], array('80', '443') ) ? '' : ':' . $_SERVER['SERVER_PORT'];
    $url .= $_SERVER['REQUEST_URI'];
    return $url;
}

// Output the XML header
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 // Start the iTunes RSS Feed: https://www.apple.com/itunes/podcasts/specs.html ?>
<rss xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" version="2.0">
  
  <?php 
    // The information for the podcast channel 
    // Mostly using get_bloginfo() here, but these can be custom tailored, as needed
  ?>
  <channel>
    <title><?php echo get_bloginfo('name'); ?></title>
    <link><?php echo get_bloginfo('url'); ?></link>
    <language><?php echo get_bloginfo ( 'language' ); ?></language>
    <copyright><?php echo date('Y'); ?> <?php echo get_bloginfo('name'); ?></copyright>
    
    <itunes:author><?php echo get_bloginfo('name'); ?></itunes:author>
    <itunes:summary><?php echo get_bloginfo('description'); ?></itunes:summary>
    <description><?php echo get_bloginfo('url'); ?></description>
    
    <itunes:owner>
      <itunes:name><?php echo get_bloginfo('name'); ?></itunes:name>
      <itunes:email><?php echo get_bloginfo('admin_email'); ?></itunes:email>
    </itunes:owner>
    
    <?php // Change to your own image. Must be at least 1400 x 1400: https://www.apple.com/itunes/podcasts/creatorfaq.html
    <itunes:image href="http://your-site.com/path/to/podcast/image.png" />
    
    <itunes:category text="Technology">
      <itunes:category text="Tech News"/>
    </itunes:category>
    <itunes:explicit>yes</itunes:explicit>
    
    <?php // Start the loop for Podcast posts
    while ( $loop->have_posts() ) : $loop->the_post(); ?>
    <item>
      <title><?php the_title_rss(); ?></title>
      <itunes:author><?php echo get_bloginfo('name'); ?></itunes:author>
      <itunes:summary><?php echo get_the_excerpt(); ?></itunes:summary>
      <?php // Retrieve just the URL of the Featured Image: http://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src
      if (has_post_thumbnail( $post->ID ) ): ?>
        <?php $image = wp_get_attachment_image_src( get_post_thumbnail_id( $post->ID ), 'full' ); ?>
        <itunes:image href="<?php echo $image[0]; ?>" />
      <?php endif; ?>
      
      <?php // Get the file field URL, filesize and date format
        $attachment_id = get_field('podcast_file');
        $fileurl = wp_get_attachment_url( $attachment_id );
        $filesize = filesize( get_attached_file( $attachment_id ) );
        $dateformatstring = _x( 'D, d M Y H:i:s O', 'Date formating for iTunes feed.' );
      ?>
      
      <enclosure url="<?php echo $fileurl; ?>" length="<?php echo $filesize; ?>" type="audio/mpeg" />
      <guid><?php echo $fileurl; ?></guid>
      <guid><?php the_field('podcast_file'); ?></guid>
      <pubDate><?php echo date($dateformatstring, $show_date); ?></pubDate>
      <itunes:duration><?php the_field('podcast_duration'); ?></itunes:duration>
    </item>
    <?php endwhile; ?>
  
  </channel>

</rss>

注意: 上面的代码假定您将 MP3 文件上传到您自己的网站/服务器。 在这种情况下,它可以获取以字节为单位的文件大小,iTunes 要求将其作为 RSS Feed 的一部分,这非常方便。 但是,如果您在其他地方托管 MP3 文件(可以很智能,大多数 Web 主机不是为提供大型资产而构建的),则此方法将不起作用。 相反,使用 ACF 添加一个额外的字段来表示字节大小,并在我们输出 `$filesize` 的地方输出它。

现在,让我们在 `my-awesome.podcast.php` 文件中调用此 RSS 模板,方法是添加以下内容

function my_podcast_rss(){
  require_once( dirname( __FILE__ ) . '/podcast-rss-template.php' );
}

整合所有内容

让我们回顾一下所有内容是如何组合在一起的。

文件

简而言之,我们现在在插件目录中有一个名为 `my-awesome-podcast` 的新文件夹。

WordPress Root Directory
└── wp-content
    └── plugins
        └── my-awesome-podcast
            ├── my-awesome-podcast.php
            └── podcast-rss-template.php
  • my-awesome.podcast.php: 此文件注册我们的插件,创建自定义 RSS 订阅源,定义新的自定义帖子类型并调用我们的 RSS 模板。
  • podcast-rss-template.php: 此文件包含我们的 RSS 订阅源的模板,以 iTunes 可读的格式提供我们 Podcast 帖子的信息,并用于将我们的内容传递给订阅者。

发布播客

继续发布新的 Podcast 帖子。选项将在 WordPress 菜单的 Podcast 下。

  • 为播客取一个标题
  • 上传播客剧集文件
  • 指定剧集时长(以 HH:MM:SS 格式)
  • (如果不在本地托管)指定剧集文件大小(以字节为单位)
  • 在内容区域提供剧集摘要

太棒了,我们刚刚发布了你的第一集播客!

将播客提交到 iTunes

最后,访问该订阅源的 URL:`[your-site]/feed/[slug]`,其中 `[slug]` 是我们在第二步的 `add_feed()` 函数中定义的。验证该订阅源不会有什么坏处 validate the feed 只要确保它健康快乐。这是你提交给 iTunes 的 URL,你可以从 iTunes 应用程序中的 iTunes Store > Podcast > 快速链接 > 提交播客中进行操作。

如果你遇到页面未找到 (404),尝试刷新你的永久链接。这可以通过从 WordPress 仪表板转到设置 > 永久链接来完成,只需要点击保存设置按钮即可。很奇怪,但确实如此。

开始播客

就是这样!一种简单但有效的利用你可能已经拥有的资源来托管播客的方法。当然,可能会有更强大甚至更优雅的解决方案,但这为我们提供了我们所需的一切,不多也不少。

更新:向 David Scanu 表示衷心的感谢。他提供了一些更新,以更正一些 RSS 验证问题,这些问题现在已反映在文章中。非常感谢!