8

我正在 wordpress 平台上创建一个网站,我希望能够在其中发布我自己的书籍文本。所以我想要的是有某种层次结构,我会在其中添加一个帖子,然后向其中添加子项(章节)。我找到了这个:

register_post_type( 'post', array(
        'labels' => array(
            'name_admin_bar' => _x( 'Post', 'add new on admin bar' ),
        ),
        'public'  => true,
        '_builtin' => true, /* internal use only. don't use this when registering your own post type. */
        '_edit_link' => 'post.php?post=%d', /* internal use only. don't use this when registering your own post type. */
        'capability_type' => 'post',
        'map_meta_cap' => true,
        'hierarchical' => false,
        'rewrite' => false,
        'query_var' => false,
        'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'post-formats' ),
    ) );

并尝试制作'hierarchical"=>true,但没有效果。任何人都可以帮忙吗?

4

8 回答 8

12

这是我的解决方法。这正是您想要的,能够为内置帖子类型帖子设置帖子父级。registred_post_type您可以通过向操作挂钩添加操作来实现此目的。只需将其添加到您的主题的functions.php。

add_action('registered_post_type', 'igy2411_make_posts_hierarchical', 10, 2 );

// Runs after each post type is registered
function igy2411_make_posts_hierarchical($post_type, $pto){

    // Return, if not post type posts
    if ($post_type != 'post') return;

    // access $wp_post_types global variable
    global $wp_post_types;

    // Set post type "post" to be hierarchical
    $wp_post_types['post']->hierarchical = 1;

    // Add page attributes to post backend
    // This adds the box to set up parent and menu order on edit posts.
    add_post_type_support( 'post', 'page-attributes' );

}

使帖子分层可能有帮助的原因可能有很多。我的用例是客户希望将他们的(已经存在的)帖子构建成问题,其中子帖子是一个问题的文章(父帖子)。

这很容易通过将查询限制为仅显示没有父母的帖子来实现,使用。

 'post_parent' => 0,

在您的查询 $args.

于 2016-10-26T11:21:52.453 回答
9

WP 4.9.*

上面的解决方法让友好的 URL 变得疯狂。

我将层次结构添加到任何现有帖子类型的解决方案:

add_filter( 'register_post_type_args', 'add_hierarchy_support', 10, 2 );
function add_hierarchy_support( $args, $post_type ){

    if ($post_type === 'post') { // <-- enter desired post type here

        $args['hierarchical'] = true;
        $args['supports'] = array_merge($args['supports'], array ('page-attributes') );
    }

    return $args;
}

在 /wp-admin/options-permalink.php 重新保存 wp 设置

于 2018-03-19T09:08:21.337 回答
6

我来这里是为了实现:

  1. 将页面属性添加到 post_type 帖子以添加父帖子
  2. 能够将页面模板添加到 post_type 帖子
  3. 能够在 post_type 帖子上获得分层永久链接结构

我能够使用接受的答案来完成 1 和 2,但不能完成 3。

注意:要完全让 2 工作,您需要在页面模板的模板评论中指定 post_type ,如下所示:

<?php
/*
Template Name: Your Post Template Name
Template Post Type: post
*/

对于 3,我发现一个插件破坏了我的 post_type 页面,而且它是很多非常糟糕的、无人维护的代码。

所以我写了一个解决方案来完成这一切,借用这个答案

(用 4.9.8 测试)

<?php

add_action('registered_post_type', 'make_posts_hierarchical', 10, 2 );

// Runs after each post type is registered
function make_posts_hierarchical($post_type, $pto){

    // Return, if not post type posts
    if ($post_type != 'post') return;

    // access $wp_post_types global variable
    global $wp_post_types;

    // Set post type "post" to be hierarchical
    $wp_post_types['post']->hierarchical = 1;

    // Add page attributes to post backend
    // This adds the box to set up parent and menu order on edit posts.
    add_post_type_support( 'post', 'page-attributes' );

}

/**
 * Get parent post slug
 * 
 * Helpful function to get the post name of a posts parent
 */
function get_parent_post_slug($post) {
  if (!is_object($post) || !$post->post_parent) {
    return false;
  }

  return get_post($post->post_parent)->post_name;
}

/**
 * 
 * Edit View of Permalink
 * 
 * This affects editing permalinks, and $permalink is an array [template, replacement]
 * where replacement is the post_name and template has %postname% in it.
 * 
 **/
add_filter('get_sample_permalink', function($permalink, $post_id, $title, $name, $post) {
  if ($post->post_type != 'post' || !$post->post_parent) {
    return $permalink;
  }

  // Deconstruct the permalink parts
  $template_permalink = current($permalink);
  $replacement_permalink = next($permalink);

  // Find string
  $postname_string = '/%postname%/';

  // Get parent post
  $parent_slug = get_parent_post_slug($post);

  $altered_template_with_parent_slug = '/' . $parent_slug . $postname_string;
  $new_template = str_replace($postname_string, $altered_template_with_parent_slug, $template_permalink);

  $new_permalink = [$new_template, $replacement_permalink];

  return $new_permalink;
}, 99, 5);

/**
 * Alter the link to the post
 * 
 * This affects get_permalink, the_permalink etc. 
 * This will be the target of the edit permalink link too.
 * 
 * Note: only fires on "post" post types.
 */
add_filter('post_link', function($post_link, $post, $leavename){

  if ($post->post_type != 'post' || !$post->post_parent) {
    return $post_link;
  }

  $parent_slug = get_parent_post_slug($post);
  $new_post_link = str_replace($post->post_name, $parent_slug . '/' . $post->post_name, $post_link);

  return $new_post_link;
}, 99, 3);

/**
 * Before getting posts
 * 
 * Has to do with routing... adjusts the main query settings
 * 
 */
add_action('pre_get_posts', function($query){
  global $wpdb, $wp_query;

  $original_query = $query;
  $uri = $_SERVER['REQUEST_URI'];

  // Do not do this post check all the time
  if ( $query->is_main_query() && !is_admin()) {

    // get the post_name
    $basename = basename($uri);
    // find out if we have a post that matches this post_name
    $test_query = sprintf("select * from $wpdb->posts where post_type = '%s' and post_name = '%s';", 'post', $basename);
    $result = $wpdb->get_results($test_query);

    // if no match, return default query, or if there's no parent post, this is not necessary
    if (!($post = current($result)) || !$post->post_parent) {
      return $original_query;
    }

    // get the parent slug
    $parent_slug = get_parent_post_slug($post);
    // concat the parent slug with the post_name to get most of the url
    $hierarchal_slug = $parent_slug . '/' . $post->post_name;

    // if the concat of parent-slug/post-name is not in the uri, this is not the right post.
    if (!stristr($uri, $hierarchal_slug)) {
      return $original_query;
    }

    // pretty high confidence that we need to override the query.
    $query->query_vars['post_type'] = ['post'];
    $query->is_home     = false; 
    $query->is_page     = true;  
    $query->is_single   = true; 
    $query->queried_object_id = $post->ID;  
    $query->set('page_id', $post->ID);

    return $query;
  }


}, 1);

您可以将其保存到文件中custom-posts-hierarchy.php并将其包含在主题中的 functions.php 文件中,或者您可以添加到顶部:

/*
Plugin Name: Custom Posts Hierarchy
Plugin URI:
Description: Add page attributes to posts and support hiearchichal
Author: Angela Murrell
Version:
Author URI: 
*/

并将其放入您的插件文件夹中。祝你好运!

于 2019-01-09T12:30:32.923 回答
3

Wordpress 中的帖子应该是典型的按时间顺序排列的博客帖子。页面是为静态内容而设计的,它们可以以开箱即用的层次结构进行组织。

对于任何页面,您都可以选择父页面。这样,您可以创建具有多个子级的嵌套层次结构。听起来像你需要的。

查看Wordpress 文档了解详细信息。

如果你有一个深而复杂的树结构,一个插件可能会帮助你管理它,比如Wordpress Page Tree。它提供了比默认的 Wordpress 页面列表更好的界面。

于 2012-05-25T09:03:00.007 回答
1

使用类似的插件CPT UI,您可以创建自定义帖子类型并将其设置为具有分层树。

然后只需检查是否page-attribute为此自定义帖子类型设置了帖子类型,并且您的帖子现在具有分层状态。

https://wordpress.org/plugins/custom-post-type-ui/

于 2014-05-06T11:46:26.777 回答
0

最好的解决方案是创建自定义分类法 [1]:http ://codex.wordpress.org/Function_Reference/register_taxonomy并创建主要的 slug - 书籍或其他东西。

于 2012-05-25T09:08:03.390 回答
0

存在插件,它为以下创建层次结构post

https://wordpress.org/plugins/add-hierarchy-parent-to-post/

于 2017-02-07T08:28:04.853 回答
0

这不是更好的选择吗?

register_post_type( 'MYPOSTTYPE',
    array(
        'labels' => array(
            'name' => __( 'MYPOSTTYPE' ),
            'singular_name' => __( 'MYPOSTTYPE' )
        ),
        'supports' => array('title', 'editor', 'page-attributes'),
        'public' => true,
        'has_archive' => true,
        'hierarchical' => true,
        'rewrite' => array('slug' => 'MYPOSTTYPE'),
    )
);

我已经添加了:

'分层' => 真的,

它有效。

于 2018-06-01T07:55:03.510 回答