В наши дни для многих проектов WordPress мы используем пользовательские типы записей. Команда разработчиков WordPress создала несколько удобных методов для их интеграции в ваши проекты. Но когда вы часто используете пользовательские типы записей, таксономии и мета-блоки, вполне вероятно, что вы будете повторяться. Вот почему мы собираемся использовать возможности этих функций WordPress для создания более мощного класса, который мы можем использовать для быстрой регистрации типов записей, таксономий и мета-блоков.
Позвоните в наш класс
Вот как мы называем наш класс, когда это будет сделано.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
 | 
 include(‘custom-post-type.php’); 
$book = new Custom_Post_Type( ‘Book’ ); 
$book->add_taxonomy( ‘category’ ); 
$book->add_taxonomy( ‘author’ ); 
$book->add_meta_box( 
    ‘Book Info’, 
    array( 
        ‘Year’ => ‘text’, 
        ‘Genre’ => ‘text’ 
    ) 
); 
$book->add_meta_box( 
    ‘Author Info’, 
    array( 
        ‘Name’ => ‘text’, 
        ‘Nationality’ => ‘text’, 
        ‘Birthday’ => ‘text’ 
    ) 
); 
 | 
Шаг 1 Класс, свойства и методы
Мы начнем с создания класса, основных свойств, конструктора и методов. В этом уроке мы наполним их нашей логикой программирования.
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
 | 
 class Custom_Post_Type 
{ 
    public $post_type_name; 
    public $post_type_args; 
    public $post_type_labels; 
         /* Class constructor */ 
    public function __construct() 
    { 
             } 
         /* Method which registers the post type */ 
    public function register_post_type() 
    { 
             } 
         /* Method to attach the taxonomy to the post type */ 
    public function add_taxonomy() 
    { 
             } 
         /* Attaches meta boxes to the post type */ 
    public function add_meta_box() 
    { 
             } 
         /* Listens for when the post type being saved */ 
    public function save() 
    { 
             } 
} 
 | 
Шаг 2 Конструктор
 Внутри конструктора мы создаем несколько важных переменных, которые используются внутри всего класса.  Мы также вызываем add_action чтобы зарегистрировать тип записи, и мы прослушиваем, когда тип записи сохраняется, чтобы мы могли сохранить метаданные нашего сообщения.  Если тип записи существует, add_action не вызывается, но $post_type_name установлено, поэтому мы можем добавить в него таксономии и мета-блоки. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
 | 
 public function __construct( $name, $args = array(), $labels = array() ) 
{ 
    // Set some important variables 
    $this->post_type_name = strtolower( str_replace( ‘ ‘, ‘_’, $name ) ); 
    $this->post_type_args = $args; 
    $this->post_type_labels = $labels; 
         // Add action to register the post type, if the post type does not already exist 
    if( ! post_type_exists( $this->post_type_name ) ) 
    { 
        add_action( ‘init’, array( &$this, ‘register_post_type’ ) ); 
    } 
         // Listen for the save post hook 
    $this->save(); 
} 
 | 
Шаг 3 Зарегистрируйте тип сообщения
  В методе register_post_type , который add_action в конструкторе, мы сначала определяем имя (с большой буквы) и множественное число.  С этим именем и множественным числом мы создаем наши метки для типа записи и перезаписываем (и объединяем) их с заданными метками из переменной $this->post_type_labels .  Затем мы создаем наши аргументы по тому же принципу. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
53 
 | 
 public function register_post_type() 
{ 
    //Capitilize the words and make it plural 
    $name = ucwords( str_replace( ‘_’, ‘ ‘, $this->post_type_name ) ); 
    $plural = $name . 
         // We set the default labels based on the post type name and plural. 
    $labels = array_merge( 
             // Default 
        array( 
            ‘name’ => _x( $plural, ‘post type general name’ ), 
            ‘singular_name’ => _x( $name, ‘post type singular name’ ), 
            ‘add_new’ => _x( ‘Add New’, strtolower( $name ) ), 
            ‘add_new_item’ => __( ‘Add New ‘ . $name ), 
            ‘edit_item’ => __( ‘Edit ‘ . $name ), 
            ‘new_item’ => __( ‘New ‘ . $name ), 
            ‘all_items’ => __( ‘All ‘ . $plural ), 
            ‘view_item’ => __( ‘View ‘ . $name ), 
            ‘search_items’ => __( ‘Search ‘ . $plural ), 
            ‘not_found’ => __( ‘No ‘ . strtolower( $plural ) . ‘ found’), 
            ‘not_found_in_trash’ => __( ‘No ‘ . strtolower( $plural ) . ‘ found in Trash’), 
            ‘parent_item_colon’ => », 
            ‘menu_name’ => $plural 
        ), 
                 // Given labels 
        $this->post_type_labels 
             ); 
         // Same principle as the labels. 
    $args = array_merge( 
             // Default 
        array( 
            ‘label’ => $plural, 
            ‘labels’ => $labels, 
            ‘public’ => true, 
            ‘show_ui’ => true, 
            ‘supports’ => array( ‘title’, ‘editor’ ), 
            ‘show_in_nav_menus’ => true, 
            ‘_builtin’ => false, 
        ), 
                 // Given args 
        $this->post_type_args 
             ); 
         // Register the post type 
    register_post_type( $this->post_type_name, $args ); 
} 
 | 
Шаг 3 Добавьте несколько таксономий
  Сначала мы проверяем, является ли параметр $name пустым.  Когда это так, мы ничего не делаем.  Когда это не так, мы создаем три переменные, в которых мы храним информацию для таксономии: $taxonomy_name , $taxonomy_labels и $taxonomy_args . 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
 | 
 public function add_taxonomy( $name, $args = array(), $labels = array() ) 
{ 
    if( ! empty( $name ) ) 
    { 
        // We need to know the post type name, so the new taxonomy can be attached to it. 
        $post_type_name = $this->post_type_name; 
        // Taxonomy properties 
        $taxonomy_name = strtolower( str_replace( ‘ ‘, ‘_’, $name ) ); 
        $taxonomy_labels = $labels; 
        $taxonomy_args = $args; 
        /* More code coming */ 
    } 
} 
 | 
После того, как мы выполнили первые проверки и затем установили некоторые переменные, мы собираемся зарегистрировать тип записи. Но сначала мы проверим, существует ли таксономия.
| 
 1 
2 
3 
4 
5 
6 
7 
8 
 | 
 if( ! taxonomy_exists( $taxonomy_name ) ) 
{ 
    /* Create taxonomy and attach it to the object type (post type) */ 
} 
else 
{ 
    /* The taxonomy already exists. 
} 
 | 
  Если таксономия не существует, мы регистрируем ее.  Мы используем add_action , но не обычным способом.  Обычно вторым параметром add_action является имя функции, но поскольку мы каждый раз используем разные параметры, мы собираемся передать безымянную функцию ( Примечание: для этой функции требуется PHP 5.3+) и использовать функцию use() .  С use() функции use() мы можем передавать переменные в безымянную функцию.  На этот раз нам нужно передать $taxonomy_name , $post_type_name и $taxonomy_args для регистрации таксономии. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
40 
41 
42 
43 
44 
45 
46 
47 
48 
49 
50 
51 
52 
 | 
 //Capitilize the words and make it plural 
$name = ucwords( str_replace( ‘_’, ‘ ‘, $name ) ); 
$plural = $name . 
// Default labels, overwrite them with the given labels. 
$labels = array_merge( 
    // Default 
    array( 
        ‘name’ => _x( $plural, ‘taxonomy general name’ ), 
        ‘singular_name’ => _x( $name, ‘taxonomy singular name’ ), 
        ‘search_items’ => __( ‘Search ‘ . $plural ), 
        ‘all_items’ => __( ‘All ‘ . $plural ), 
        ‘parent_item’ => __( ‘Parent ‘ . $name ), 
        ‘parent_item_colon’ => __( ‘Parent ‘ . $name . ‘:’ ), 
        ‘edit_item’ => __( ‘Edit ‘ . $name ), 
        ‘update_item’ => __( ‘Update ‘ . $name ), 
        ‘add_new_item’ => __( ‘Add New ‘ . $name ), 
        ‘new_item_name’ => __( ‘New ‘ . $name . ‘ Name’ ), 
        ‘menu_name’ => __( $name ), 
    ), 
    // Given labels 
    $taxonomy_labels 
); 
// Default arguments, overwritten with the given arguments 
$args = array_merge( 
    // Default 
    array( 
        ‘label’ => $plural, 
        ‘labels’ => $labels, 
        ‘public’ => true, 
        ‘show_ui’ => true, 
        ‘show_in_nav_menus’ => true, 
        ‘_builtin’ => false, 
    ), 
    // Given 
    $taxonomy_args 
); 
// Add the taxonomy to the post type 
add_action( ‘init’, 
    function() use( $taxonomy_name, $post_type_name, $args ) 
    { 
        register_taxonomy( $taxonomy_name, $post_type_name, $args ); 
    } 
); 
 | 
  Когда таксономия не существует, мы прикрепляем ее только к нашему типу записи.  Как и раньше, мы используем безымянную функцию и функцию use() .  На этот раз нам нужно только передать $taxonomy_name и $post_type_name . 
| 
 1 
2 
3 
4 
5 
6 
 | 
 add_action( ‘init’, 
    function() use( $taxonomy_name, $post_type_name ) 
    { 
        register_taxonomy_for_object_type( $taxonomy_name, $post_type_name ); 
    } 
); 
 | 
Шаг 4, мета-боксы
Для регистрации мета-блоков нам нужно имя типа записи, поэтому сначала мы определим это. После этого нам понадобятся некоторые переменные для самого мета-блока, и мы сделаем пользовательские мета-поля глобальными, чтобы мы могли получить к ним доступ в хуке сохранения. Мы не будем здесь подробно рассказывать, потому что Тэмми Харт уже сделала очень полезное руководство по использованию мета-блоков многократного использования .
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
 | 
 public function add_meta_box( $title, $fields = array(), $context = ‘normal’, $priority = ‘default’ ) 
{ 
    if( ! empty( $title ) ) 
    { 
        // We need to know the Post Type name again 
        $post_type_name = $this->post_type_name; 
        // Meta variables 
        $box_id = strtolower( str_replace( ‘ ‘, ‘_’, $title ) ); 
        $box_title = ucwords( str_replace( ‘_’, ‘ ‘, $title ) ); 
        $box_context = $context; 
        $box_priority = $priority; 
                 // Make the fields global 
        global $custom_fields; 
        $custom_fields[$title] = $fields; 
                 /* More code coming */ 
    } 
     } 
 | 
  Когда мы устанавливаем переменные и глобальные переменные, мы регистрируем мета-поле с помощью add_action .  Как и раньше, мы используем безымянную функцию.  На этот раз нам нужны $box_id , $box_title , $post_type_name , $box_context , $box_priority и $fields . 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
36 
37 
38 
39 
 | 
 add_action( ‘admin_init’, 
    function() use( $box_id, $box_title, $post_type_name, $box_context, $box_priority, $fields ) 
    { 
        add_meta_box( 
            $box_id, 
            $box_title, 
            function( $post, $data ) 
            { 
                global $post; 
                                 // Nonce field for some validation 
                wp_nonce_field( plugin_basename( __FILE__ ), ‘custom_post_type’ ); 
                                 // Get all inputs from $data 
                $custom_fields = $data[‘args’][0]; 
                                 // Get the saved values 
                $meta = get_post_custom( $post->ID ); 
                                 // Check the array and loop through it 
                if( ! empty( $custom_fields ) ) 
                { 
                    /* Loop through $custom_fields */ 
                    foreach( $custom_fields as $label => $type ) 
                    { 
                        $field_id_name = strtolower( str_replace( ‘ ‘, ‘_’, $data[‘id’] ) ) . 
                                                 echo ‘<label for=»‘ . $field_id_name . ‘»>’ . 
                    } 
                } 
                         }, 
            $post_type_name, 
            $box_context, 
            $box_priority, 
            array( $fields ) 
        ); 
    } 
); 
 | 
Шаг 5 Сохраните метаданные сообщения
  Сохраните все метаданные поста.  Мы перебираем их, используя глобальные $custom_fields .  Это также быстрое освещение, см . Учебник Тэмми Харт о мета-блоках многократного использования . 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
19 
20 
21 
22 
23 
24 
25 
26 
27 
28 
29 
30 
31 
32 
33 
34 
35 
 | 
 public function save() 
{ 
    // Need the post type name again 
    $post_type_name = $this->post_type_name; 
    add_action( ‘save_post’, 
        function() use( $post_type_name ) 
        { 
            // Deny the WordPress autosave function 
            if( defined(‘DOING_AUTOSAVE’) && DOING_AUTOSAVE ) return; 
            if ( ! wp_verify_nonce( $_POST[‘custom_post_type’], plugin_basename(__FILE__) ) ) return; 
                     global $post; 
                         if( isset( $_POST ) && isset( $post->ID ) && get_post_type( $post->ID ) == $post_type_name ) 
            { 
                global $custom_fields; 
                                 // Loop through each meta box 
                foreach( $custom_fields as $title => $fields ) 
                { 
                    // Loop through all fields 
                    foreach( $fields as $label => $type ) 
                    { 
                        $field_id_name = strtolower( str_replace( ‘ ‘, ‘_’, $title ) ) . 
                                                 update_post_meta( $post->ID, $field_id_name, $_POST[‘custom_meta’][$field_id_name] ); 
                    } 
                                 } 
            } 
        } 
    ); 
} 
 | 
Шаг 6 Оптимизация
  Как видите, мы используем strtolower( str_replace( ' ', '_', $string ) ) и ucwords( str_replace( '_', ' ', $string ) ) несколько раз.  Причина создания этого класса в том, что мы не повторяем себя, поэтому мы не хотим делать это и в этой части.  Вот почему мы создаем несколько вспомогательных методов.  Таким образом, мы можем сделать это: $name = self::beautify( $string );  вместо $name = strtolower( str_replace( ' ', '_', $title ) ); 
| 
 1 
2 
3 
4 
5 
6 
7 
8 
9 
 | 
 public static function beautify( $string ) 
{ 
    return ucwords( str_replace( ‘_’, ‘ ‘, $string ) ); 
} 
public static function uglify( $string ) 
{ 
    return strtolower( str_replace( ‘ ‘, ‘_’, $string ) ); 
} 
 | 
  Другой момент — формы множественного числа, которые мы создаем.  Мы просто создаем их, добавляя к слову «s».  Но что происходит, когда слово оканчивается на «у»?  По этой причине мы создаем вспомогательный метод для определения формы слова во множественном числе.  Теперь мы можем легко сделать это: $plural = self::pluralize( $string ) и форма нашего слова во множественном числе будет определена. 
| 
 01 
02 
03 
04 
05 
06 
07 
08 
09 
10 
11 
12 
13 
14 
15 
16 
17 
18 
 | 
 public static function pluralize( $string ) 
{ 
    $last = $string[strlen( $string ) — 1]; 
         if( $last == ‘y’ ) 
    { 
        $cut = substr( $string, 0, -1 ); 
        //convert y to ies 
        $plural = $cut . 
    } 
    else 
    { 
        // just attach an s 
        $plural = $string . 
    } 
         return $plural; 
} 
 | 
Заворачивать
И теперь мы закончили. Теперь вы можете использовать этот класс для простой регистрации типов записей, таксономий и мета-блоков. Если у вас есть предложения или вопросы, просто оставьте комментарий, чтобы мы могли поговорить об этом. Надеюсь увидеть вас в следующий раз!
Кроме того, я хотел бы отдать должное Джеффри Вей. Я использовал его урок как вдохновение для своего урока и для этого урока. Кроме того, я хотел бы поблагодарить Тэмми Харт за создание учебного пособия по использованию мета-блоков . Посмотрите на их работу.