具有分类和自定义字段的有趣的自定义POST类型插件

时间:2011-01-21 作者:NetConstructor.com

我创建了一个名为“事件”的自定义帖子类型,还创建了一个自定义分类法,它只显示在这个特定的帖子类型上,管理员必须通过它选择一个“事件类别”(术语)。

当前在公共网站上,当请求事件详细信息页面时,其显示如下:

http://www.domain-name.com/events/title-of-the-event

此外,在公共端,web浏览器只能访问特定的事件类别,以查看url如下所示的所有关联事件:

http://www.domain-name.com/events/event-category

以上两种情况目前都可以正常工作。

我遇到的问题是,我想自定义事件详细信息页面的URL slug,如下所示:

我希望它包含分类术语和特定的自定义字段,而不是根据输入的标题构建事件详细信息页面slug。最终,我希望它看起来像这样:

http://www.domain-name.com/events/<taxonomy-term>-event-title-<custom-field>/
  • <taxonomy-term> 是事件类别(我对metabox进行编程的方式,管理员只能选择一个术语)
  • <custom-field> 是一个特定的自定义字段,用户需要输入该字段才能保存事件日志
1 个回复
最合适的回答,由SO网友:MikeSchinkel 整理而成

好吧,如果我在写这篇文章之前考虑过需要做多少工作,你现在就无法给我打分了。:)不用说,它相当复杂(虽然我不认为它真的应该是这样,但它就是这样。)

首先,你不能(轻松地)随心所欲;问题是如何区分这两个URL:

事件类型=“白天时间”,事件标题=“更改”

事件类型为“天”,事件标题为“更改时间”

这两个网站的URL都有一部分是这样的,我们怎样才能分辨出哪个是哪个?

day-time-for-a-change
因此,我修改了您的模式,使用波浪线(~)作为分隔符,效果很好:

http://www.domain-name.com/events/<taxonomy-term>~event-title~<custom-field>/
总之,我写了一个插件,可以满足您的需要。它执行以下操作:

它使用$wp_rewrite->add_rule().

它应用该模式,使用\'post_type_link\' 挂钩,以及

它通过使用\'get_sample_permalink_html\' hook(我没有尝试显示完整的URL,因为这对于我免费编写的东西来说太棘手了。:)

因此,编辑屏幕是这样的:

Screenshot of Event Edit Screen on WordPress
(来源:mikeschinkel.com)

在前端生成此视图:

Example of Custom URLs in WordPress
(来源:mikeschinkel.com)

下面是插件代码(如果有问题,请告诉我,但不要太多)

<?php 
/*
Plugin Name: SEO URLs for Events
*/
if (!class_exists(\'SeoUrlsForEvents\')) {
  class SeoUrlsForEvents {
    static function on_load() {
      add_action(\'init\', array(__CLASS__,\'init\'));
      add_filter(\'post_type_link\', array(__CLASS__,\'post_type_link\'),10,4);
      add_filter(\'get_sample_permalink_html\',array(__CLASS__,\'get_sample_permalink_html\'),10,4);
    }
    static function get_sample_permalink_html($sample, $post_id, $new_title, $new_slug) {
      $post = get_post($post_id);
      if ($post->post_type==\'event\') {
        $post_slug = self::make_post_slug($post);
        if ($post_slug) {
          $sample = str_replace(\'<strong>Permalink:</strong>\',\'<strong>Permalink Slug:</strong>\',$sample);
          $sample = preg_replace(\'#(<span id="sample-permalink">).+?(<span id="editable-post-name" title="Click to edit this part of the permalink">).+?</span>/</span>#Us\',"$1$2{$post->post_name}</span></span>",$sample);
          $permalink = get_post_permalink($id);
          $sample = preg_replace("#(<span id=\'view-post-btn\'><a href=\').+?(\' class=\'button\' target=\'_blank\'>View Post</a></span>)#","$1{$permalink}$2",$sample);
        }
      }
      return $sample;
    }
    static function make_post_slug($post) {
      $post_slug = false;
      $post = (object)$post;
      if ($post->post_type==\'event\') {
        $when = get_post_meta($post->ID,\'when\',true);
        if (!empty($when)) { // If we don\'t have a when, use default
          $types = wp_get_object_terms($post->ID,\'event-type\');
          if (count($types)) // If we don\'t have an event-type, use default else use the first one
            $post_slug = "{$types[0]->slug}~{$post->post_name}~{$when}/";
        }
      }
      return $post_slug;
    }
    static function post_type_link($post_link, $post, $leavename, $sample) {
      if ($post->post_type==\'event\' && $sample) {
        $post_link = \'%event%\';
      } else {
        $post_slug = self::make_post_slug($post);
        if ($post_slug) {
          $post_link = get_bloginfo(\'wpurl\') . \'/events/\' . $post_slug;
        }
      }
      return $post_link;
    }
    static function activate() {
      global $wp_rewrite;
      $wp_rewrite->add_rule(\'events/([^~]+)~([^~]+)~([^/]+)\',\'index.php?post_type=event&taxonomy=event-type&term=$matches[1]&name=$matches[2]&meta_key=when&meta_value=$matches[3]\', \'top\');
      $wp_rewrite->flush_rules(false);
    }
    static function init() {
      register_post_type(\'event\',
        array(
          \'label\'           => \'Events\',
          \'public\'          => true,
          \'rewrite\'         => array(\'slug\' => \'events\'),
          \'hierarchical\'    => false,
          \'supports\'        => array(\'title\',\'editor\',\'custom-fields\'),
        )
      );
      register_taxonomy(\'event-type\', \'event\', array(
        \'hierarchical\'    => false,
        \'label\'           => \'Event Types\',
        \'rewrite\'         => array(\'slug\' => \'event-types\' ),
        )
      );
    }
  }
  SeoUrlsForEvents::on_load();
}
register_activation_hook(__FILE__,array(\'SeoUrlsForEvents\',\'activate\'));

结束

相关推荐

在不删除功能的情况下删除“slug”的Metabox

这里有一个有趣的问题。我最近注意到,如果您使用该代码remove_meta_box(\'slugdiv\', \'post\', \'normal\'); 当您单击页面标题下的url slug时,实际上无法修改slug。要澄清的是,当您为slugdiv使用remove\\u meta\\u框时,metabox和屏幕选项将被删除,但是您仍然可以单击文章标题下的url来编辑它。。。然而,当你去更新/发布帖子时,你所做的任何修改都不会生效。我的目标是从post edit屏幕中删除同一个metabox