WordPress: tipo de publicación personalizada, enviar datos a “register_meta_box_cb” Arg

12 minutos de lectura

avatar de usuario
Kelderic

Estoy agregando varios tipos de publicaciones personalizadas a un sitio web de WordPress y estoy tratando de optimizar el código mediante el uso de variables y funciones de fusión. Pude enviar 2 variables al create_rma_project_post_type función que solía register_post_type. Me gustaría hacer lo mismo con el argumento que adjunta la función de creación de metabox. El primer código a continuación funciona completamente. Usa register_meta_box_cb llamar add_project_metaboxes:

add_action('init', create_rma_project_post_type('project','our-people'));
function create_rma_project_post_type($post_type,$display_page) {
    $prefix = 'rma';
    $post_label = ucfirst($post_type);

    register_post_type($prefix.'_'.$post_type,
        array(
            'labels' => array(
                'name' => __( $post_label.'s' ),
                'singular_name' => __( $post_label ),
                'all_items' => __( $post_label.' List' ),
                'add_new' => __( 'Add New '.$post_label),
                'add_new_item' => __( 'Add New '.$post_label),
                'edit_item' => __( 'Edit '.$post_label),
                'new_item' => __( 'New '.$post_label),
                'view_item' => __( 'View '.$post_label),
                'search_items' => __( 'Search'),
                'parent_item_colon' => 'about-us/'.$display_page,
            ),
            'public' => true,
            'has_archive' => false,
            'rewrite' => array('slug' => 'about-us/'.$display_page,'with_front' => false),
            'supports' => array('title','editor','thumbnail'),
            'register_meta_box_cb' => 'add_project_metaboxes',
        )
    );
}

function add_project_metaboxes() {
    add_meta_box('rma_project_metabox_information', 'Project Information', 'rma_project_metabox_information_callback', 'rma_project', 'normal', 'default');
}

Lo que quiero hacer es cambiar la llamada de metabox para enviar una variable, con el objetivo de poder eliminar la palabra “proyectos” de la función y usar la función única para todos los tipos de publicaciones personalizadas.

Esto es lo que me gustaría que leyera esa línea:

            'register_meta_box_cb' => add_project_metaboxes($post_type),

Cuando hago eso, no funciona. Tampoco ninguno de estos:

            'register_meta_box_cb' => 'add_project_metaboxes($post_type)',
            'register_meta_box_cb' => function(add_project_metaboxes($post_type)),
            'register_meta_box_cb' => function('add_project_metaboxes($post_type)'),
            'register_meta_box_cb' => sprintf( __('add_project_metaboxes(%s)'), $post_type ),

Mi primera pregunta es, ¿es esto posible actualmente con WordPress? Si es así, ¿cómo puedo hacer eso? Agradezco cualquier ayuda, y si necesita aclaración de cualquier cosa por favor hágamelo saber.


Editar 2017

Usando esta y otras respuestas, creé un conjunto de clases auxiliares para facilitar la administración de CTP. Si desea ver el producto terminado, consulte:

https://gist.github.com/Kelderic/dc641aced67f0c0cb0a4a1ded17fa0d4

avatar de usuario
birgire

los register_meta_box_cb devolución de llamada tiene un argumento de entrada, a saber, el WP_Post objeto de la publicación editada actualmente.

Así que creo que debería poder obtener el tipo de publicación de ese objeto usando el get_post_type() Función de WordPress.

Si echas un vistazo a la código fuente Para el register_post_type() encontrará que contiene esta parte:

 if ( $args->register_meta_box_cb )
     add_action( 'add_meta_boxes_' . $post_type, $args->register_meta_box_cb, 10, 1 );

Así que intenta reemplazar:

'register_meta_box_cb' => 'add_project_metaboxes',

con:

'register_meta_box_cb' => 'custom_add_metaboxes',

dónde:

function custom_add_metaboxes( $post )
{

    // get the current post type
    $post_type = get_post_type( $post );

    // your logic for the add_meta_box code
    // ...

}

contiene la lógica basada en el tipo de publicación actual.

Actualizar:

es una forma de almacenar/asociar una matriz de datos a un tipo de publicación personalizada?

a) Sí, puedes usar el update_post_meta() para almacenar datos asociados a un tipo de publicación personalizada con un determinado $post_id:

update_post_meta( $post_id, $meta_key, $meta_value );

dónde $meta_value puede ser un cuerda o un formación. Por ejemplo:

update_post_meta( 38, 'my_data', array( 'somekey' => 'somevalue' ) );

Para obtener los datos de la matriz, puede usar get_post_meta():

$data = get_post_meta( 38, 'my_data', FALSE );

b) Si desea almacenar una matriz de datos, que está relacionada con todas las publicaciones en un determinado tipo de publicación personalizada, puede usar actualizar_opción() para guardarlo y get_option() para ir a buscarlo

Por ejemplo, puedes usar:

$data = array( 
              'cpt1' => array( 'somekey1' => 'somevalue1' ),
              'cpt2' => array( 'somekey2' => 'somevalue2' ),
);

update_option( 'my_data', $data );

para almacenar el $data matriz y

$data = get_option( 'my_data' );

para recuperarlo.

Espero que esto ayude.

  • ¡Hermoso! No me di cuenta de que la función llamada por register_meta_box_cb sería enviado el $post automáticamente. Por casualidad, ¿sabe si hay una forma de almacenar/asociar una matriz de datos a un tipo de publicación personalizada?

    – Kelderic

    16/03/2014 a las 21:17

  • @AndyM Actualicé la respuesta, con un ejemplo de cómo almacenar/asociar una matriz de datos a un tipo de publicación personalizada. Espero que esto ayude.

    – birgire

    17 de marzo de 2014 a las 1:57

  • Se ve muy bien, te otorgaré la recompensa en 3 horas cuando me lo permita.

    – Kelderic

    17 de marzo de 2014 a las 14:05

  • @AndyM Gracias y mucha suerte con tu proyecto.

    – birgire

    17 de marzo de 2014 a las 15:27

no es realmente un problema de wordpress, sino más bien una cuestión de cómo se llaman las funciones cuando se almacenan. si está buscando un nombre de función, debe darlo como tal.

Veo lo que está tratando de hacer, si desea llamar a add_project_metaboxes ($ post_type) justo después de declarar la matriz, add_meta_boxes solía estar conectado a “init”, por lo que puede funcionar. Por cierto… la función tal como existe arriba no funcionará a menos que la modifique para tomar un parámetro.

Si no, un objeto de tipo OOP podría ser lo que está buscando.

  • Bueno, sí y no. Es una pregunta cómo llama WordPress específicamente a las funciones que están almacenadas. Vocación add_project_metaboxes() podría ser simplemente llamado desde adentro create_rma_project_post_type posiblemente, sin embargo, ahora que lo mencionas. Le daré un vistazo. ¿Podría aclarar la última oración del segundo párrafo, porque todo en el primer bloque de código funciona como está, así que no estoy seguro de lo que quiere decir?

    – Kelderic

    13 de marzo de 2014 a las 12:23

  • sí, si llama a add_project_metaboxes() funcionará, pero si intenta llamar a add_project_metaboxes($var), necesita modificar la función para tomar una variable. ¡Pero probablemente estabas haciendo esto de todos modos!

    – David

    13/03/2014 a las 18:00

  • Oh sí. Tendría que cambiar todas las instancias de "project" a .$post_type.y coloque un parámetro para capturar los datos enviados. Esa parte no es el problema.

    – Kelderic

    13/03/2014 a las 18:41

  • Si bien agradezco la respuesta, esto en realidad no responde a mi pregunta, porque hacer una llamada a add_project_metaboxes dentro de create_rma_project_post_type no funciona Voy a poner una recompensa y ver si puedo obtener alguna otra idea. Siéntase libre de editar su respuesta si se le ocurre algo.

    – Kelderic

    16 de marzo de 2014 a las 1:37

  • agregue add_action(‘init’, ‘add_project_metaboxes’) a la función rma project function, no a la función en sí. Pero vea a continuación una solución basada en clases que debería facilitar mucho las cosas para múltiples tipos de publicaciones nuevas.

    – David

    17 de marzo de 2014 a las 1:30


avatar de usuario
David

Estoy publicando una clase base que uso para tipos de publicaciones personalizadas, no es mi código y no puedo recordar dónde lo recogí, ¡pero crédito al creador! funciona muy bien para lo que suelo crear publicaciones personalizadas y debería funcionar con su código (vea a continuación, intenté reproducir rápidamente su función). ¡Espero que ayude!

por cierto: puede almacenar información personalizada para la publicación usando post_meta (puede obtener esto usando el postid). avíseme si esto no está claro y si hago algo en pastebin.

class base_posttype {

public $post_type_name;
public $post_type_variables;
public $post_type_labels;
public $meta_keys;
public $result= array();

public function __construct( $name, $variables= array(), $labels=array() ) {

     $this->post_type_name = $name ;
     $this->post_type_variables = $variables;
     $this->post_type_labels = $labels;


     if( ! post_type_exists ( $this-> post_type_name ) ){

        add_action ('init', array( &$this, 'register_post_type' ) );

     }

     $this->save();

} //------------end construct------------------------------------------


public function register_post_type() {

    $name       = ucwords( str_replace( '_', ' ', $this->post_type_name ) );
    $plural     = $name . 's';

    $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
    ),


    $this->post_type_labels

    );


    $args = array_merge(


    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
    $this->result[]=register_post_type( $this->post_type_name, $args );    
}


/* attach the taxonomy to the post type */
public function add_taxonomy( $name, $args = array(), $labels = array() ) {

     if( ! empty( $name ) ) {
    $post_type_name = $this->post_type_name;

    // Taxonomy properties
    $taxonomy_name      = strtolower( str_replace( ' ', '_', $name ) );
    $taxonomy_labels    = $labels;
    $taxonomy_args      = $args;

    if( ! taxonomy_exists( $taxonomy_name ) ) {

    //Capitilize the words and make it plural
    $name       = ucwords( str_replace( '_', ' ', $name ) );
    $plural     = $name . 's';

    // 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 );
        });

    } else {

        add_action( 'init', function() use( $taxonomy_name, $post_type_name ) {
            register_taxonomy_for_object_type( $taxonomy_name, $post_type_name );
        });

    }


    }
}

/* Attaches meta boxes to the post type */
public function add_meta_box( $title, $fields = array(), $context="normal", $priority = 'default' ) {

    // 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;

    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'] ) ) . '_' . strtolower( str_replace( ' ', '_', $label ) );

                    echo '<label for="' . $field_id_name . '">' . $label . '</label><input type="text" name="custom_meta[' . $field_id_name . ']" id="' . $field_id_name . '" value="' . $meta[$field_id_name][0] . '" />';
                }
            }},
            $post_type_name,
            $box_context,
            $box_priority,
            array( $fields )
            );
        });

}



/* Listens for when the post type being saved */
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 ) ) . '_' . strtolower( str_replace( ' ', '_', $label ) );

                    update_post_meta( $post->ID, $field_id_name, $_POST['custom_meta'][$field_id_name] );
                }

            }
        }
    });

}
}

y luego puede crear la publicación usando esta clase, por ejemplo

 class project_post_type {

public function __construct () {


$project= new base_posttype ('project', array(
'has_archive' => TRUE,
        'menu_position' => 10,
        'rewrite' => array(
            'slug' => 'our-people',
            'with_front' => FALSE,
        ),
        'supports' => array( 'title', 'editor', 'thumbnail', 'comments', 'custom-fields', 'revisions' ),
        'menu_icon' => AD_URL . '/resources/img/adlogo.png'
    ));

    $project->add_taxonomy( 'location');
$project->add_taxonomy ('categories', array(
'hierarchical' => true
));

$project->add_meta_box( 'Project Info' , array(
    'price' => 'text',
    'condition' => 'text',
    'age' => 'text',
    'expiration_date' => 'text', // int
    'fee' => 'text',
    'discount' => 'text',
    'due' => 'text',
    'paid' => 'text',
    'sold' => 'text' //boolan
    )
);

}
}

$project= new project_post_type;

normalmente, si tengo una serie de datos que necesito usar para el tipo de publicación, lo configuro dentro de la clase, por lo que un método para extraer las claves meta y un método para guardar, la mayoría de las veces no es necesario, pero en algunas ocasiones donde Tengo gustos de enviar formularios desde el front-end, es útil.

  • Esto parece interesante pero no tan directamente aplicable como la respuesta de birgire. Sin embargo, agradezco la ayuda, ¡así que +1!

    – Kelderic

    17 de marzo de 2014 a las 14:04

¿Ha sido útil esta solución?