1. Code
  2. WordPress
  3. Plugin Development

Creación de testimonios de clientes con tipos de entradas personalizadas

Scroll to top

Spanish (Español) translation by Eva Collados Pascual (you can also view the original English article)

Si estás dirigiendo cualquier tipo de negocio online, es una buena idea conseguir opiniones de tus clientes sobre lo que piensan en relación a los servicios que les proporcionaste.

En primer lugar, esto puede beneficiarle al ofrecerte feedback sobre formas en las que podrías mejorar aspectos de tu negocio, pero sobre todo, puede darte grandes testimonios, lo que te podría ayudar a persuadir a clientes potenciales de manera que utilicen tus servicios.

La forma más fácil de añadir esta funcionalidad a tu sitio sería incluirla en forma de plugin. He reunido todos los archivos necesarios e incluido un enlace de descarga para el anterior plugin Client Testimonials.


Tipo de entrada personalizada del testimonio

Los tipos de entradas personalizadas son ideales para separar el contenido según distintas necesidades. Especialmente si tu contenido personalizado no necesita todas las campanas y silbatos de una entrada estándar.

En este tutorial, voy a mostrarte cómo puedes crear rápidamente un tipo de entrada personalizada para tus testimonios que solo requiere el editor de texto y tres meta boxes personalizados.

1
add_action( 'init', 'testimonials_post_type' );
2
function testimonials_post_type() {
3
	$labels = array(
4
		'name' => 'Testimonials',
5
		'singular_name' => 'Testimonial',
6
		'add_new' => 'Add New',
7
		'add_new_item' => 'Add New Testimonial',
8
		'edit_item' => 'Edit Testimonial',
9
		'new_item' => 'New Testimonial',
10
		'view_item' => 'View Testimonial',
11
		'search_items' => 'Search Testimonials',
12
		'not_found' =>  'No Testimonials found',
13
		'not_found_in_trash' => 'No Testimonials in the trash',
14
		'parent_item_colon' => '',
15
	);
16
17
	register_post_type( 'testimonials', array(
18
		'labels' => $labels,
19
		'public' => true,
20
		'publicly_queryable' => true,
21
		'show_ui' => true,
22
		'exclude_from_search' => true,
23
		'query_var' => true,
24
		'rewrite' => true,
25
		'capability_type' => 'post',
26
		'has_archive' => true,
27
		'hierarchical' => false,
28
		'menu_position' => 10,
29
		'supports' => array( 'editor' ),
30
		'register_meta_box_cb' => 'testimonials_meta_boxes', // Callback function for custom metaboxes

31
	) );
32
}

Añadir un metabox

Ahora que has creado un tipo de entrada personalizada para los testimonios y has establecido una devolución de llamada para los meta boxes personalizados, debes configurar cómo se mostrarán esos metaboxes. Así que a continuación tienes que usar la función add_meta_box() para hacer justo esto.

1
function testimonials_meta_boxes() {
2
	add_meta_box( 'testimonials_form', 'Testimonial Details', 'testimonials_form', 'testimonials', 'normal', 'high' );
3
}
4
5
function testimonials_form() {
6
	$post_id = get_the_ID();
7
	$testimonial_data = get_post_meta( $post_id, '_testimonial', true );
8
	$client_name = ( empty( $testimonial_data['client_name'] ) ) ? '' : $testimonial_data['client_name'];
9
	$source = ( empty( $testimonial_data['source'] ) ) ? '' : $testimonial_data['source'];
10
	$link = ( empty( $testimonial_data['link'] ) ) ? '' : $testimonial_data['link'];
11
12
	wp_nonce_field( 'testimonials', 'testimonials' );
13
	?>
14
	<p>
15
		<label>Client's Name (optional)</label><br />
16
		<input type="text" value="<?php echo $client_name; ?>" name="testimonial[client_name]" size="40" />
17
	</p>
18
	<p>
19
		<label>Business/Site Name (optional)</label><br />
20
		<input type="text" value="<?php echo $source; ?>" name="testimonial[source]" size="40" />
21
	</p>
22
	<p>
23
		<label>Link (optional)</label><br />
24
		<input type="text" value="<?php echo $link; ?>" name="testimonial[link]" size="40" />
25
	</p>
26
	<?php
27
}

Hay tres campos que debes incluir al configurar los datos para tu testimonio: el nombre del cliente, su empresa y un enlace a su sitio web. A veces, es posible que no tengas los tres, pero la información mínima que deberías requerir es el nombre del cliente.

Consejo: Cada vez que añadas un metabox, cerciórate de usar un nonce para securizar el formulario. Es algo necesario. Lee más sobre los nonces en el códice de WordPress.

Guardar el meta personalizado

Dado que has añadido un metabox personalizado, tendrás que asegurarte de que todos los datos sean validados y almacenados. Debes enganchar a la acción save_post y configurar una función de devolución de llamada.

1
add_action( 'save_post', 'testimonials_save_post' );
2
function testimonials_save_post( $post_id ) {
3
	if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
4
		return;
5
6
	if ( ! empty( $_POST['testimonials'] ) && ! wp_verify_nonce( $_POST['testimonials'], 'testimonials' ) )
7
		return;
8
9
	if ( ! empty( $_POST['post_type'] ) && 'page' == $_POST['post_type'] ) {
10
		if ( ! current_user_can( 'edit_page', $post_id ) )
11
			return;
12
	} else {
13
		if ( ! current_user_can( 'edit_post', $post_id ) )
14
			return;
15
	}
16
17
	if ( ! wp_is_post_revision( $post_id ) && 'testimonials' == get_post_type( $post_id ) ) {
18
		remove_action( 'save_post', 'testimonials_save_post' );
19
20
		wp_update_post( array(
21
			'ID' => $post_id,
22
			'post_title' => 'Testimonial - ' . $post_id
23
		) );
24
25
		add_action( 'save_post', 'testimonials_save_post' );
26
	}
27
28
	if ( ! empty( $_POST['testimonial'] ) ) {
29
		$testimonial_data['client_name'] = ( empty( $_POST['testimonial']['client_name'] ) ) ? '' : sanitize_text_field( $_POST['testimonial']['client_name'] );
30
		$testimonial_data['source'] = ( empty( $_POST['testimonial']['source'] ) ) ? '' : sanitize_text_field( $_POST['testimonial']['source'] );
31
		$testimonial_data['link'] = ( empty( $_POST['testimonial']['link'] ) ) ? '' : esc_url( $_POST['testimonial']['link'] );
32
33
		update_post_meta( $post_id, '_testimonial', $testimonial_data );
34
	} else {
35
		delete_post_meta( $post_id, '_testimonial' );
36
	}
37
}

Personalizar la visualización de lista

Después de crear el primer testimonio, verás que aparecerá en la vista de lista de tu tipo de entrada personalizada; sin embargo, no verás ninguno de los metadatos personalizados.

Esto tiene fácil solución: Sólo tienes que añadir un par de funciones más para personalizar las columnas de la visualización de lista para que aparezca toda la información que quieras.

1
add_filter( 'manage_edit-testimonials_columns', 'testimonials_edit_columns' );
2
function testimonials_edit_columns( $columns ) {
3
	$columns = array(
4
		'cb' => '<input type="checkbox" />',
5
		'title' => 'Title',
6
		'testimonial' => 'Testimonial',
7
		'testimonial-client-name' => 'Client\'s Name',
8
		'testimonial-source' => 'Business/Site',
9
		'testimonial-link' => 'Link',
10
		'author' => 'Posted by',
11
		'date' => 'Date'
12
	);
13
14
	return $columns;
15
}
16
17
add_action( 'manage_posts_custom_column', 'testimonials_columns', 10, 2 );
18
function testimonials_columns( $column, $post_id ) {
19
	$testimonial_data = get_post_meta( $post_id, '_testimonial', true );
20
	switch ( $column ) {
21
		case 'testimonial':
22
			the_excerpt();
23
			break;
24
		case 'testimonial-client-name':
25
			if ( ! empty( $testimonial_data['client_name'] ) )
26
				echo $testimonial_data['client_name'];
27
			break;
28
		case 'testimonial-source':
29
			if ( ! empty( $testimonial_data['source'] ) )
30
				echo $testimonial_data['source'];
31
			break;
32
		case 'testimonial-link':
33
			if ( ! empty( $testimonial_data['link'] ) )
34
				echo $testimonial_data['link'];
35
			break;
36
	}
37
}

Eso es casi todo lo que necesitas para configurar testimonios en el administrador de WordPress. Pero, ¿cómo se pueden mostrar en el front-end? Echemos un vistazo a algunas distintas formas de mostrar tus testimonios.


Mostrar los testimonios

Si deseas mostrar un testimonio en algún lugar de una de las plantillas de página de tu tema, tendrás que crear una función. Aquí tienes una rápida que te permitirá mostrar testimonios de clientes. Puedes utilizar los parámetros para seleccionar un testimonio concreto utilizando su ID, o incluso mostrar uno aleatorio pasando un valor 'orderby'.

1
/**

2
 * Display a testimonial

3
 *

4
 * @param  int $post_per_page  The number of testimonials you want to display

5
 * @param  string $orderby  The order by setting  https://codex.wordpress.org/Class_Reference/WP_Query#Order_.26_Orderby_Parameters

6
 * @param  array $testimonial_id  The ID or IDs of the testimonial(s), comma separated

7
 *

8
 * @return  string  Formatted HTML

9
 */
10
function get_testimonial( $posts_per_page = 1, $orderby = 'none', $testimonial_id = null ) {
11
	$args = array(
12
		'posts_per_page' => (int) $posts_per_page,
13
		'post_type' => 'testimonials',
14
		'orderby' => $orderby,
15
		'no_found_rows' => true,
16
	);
17
	if ( $testimonial_id )
18
		$args['post__in'] = array( $testimonial_id );
19
20
	$query = new WP_Query( $args  );
21
22
	$testimonials = '';
23
	if ( $query->have_posts() ) {
24
		while ( $query->have_posts() ) : $query->the_post();
25
			$post_id = get_the_ID();
26
			$testimonial_data = get_post_meta( $post_id, '_testimonial', true );
27
			$client_name = ( empty( $testimonial_data['client_name'] ) ) ? '' : $testimonial_data['client_name'];
28
			$source = ( empty( $testimonial_data['source'] ) ) ? '' : ' - ' . $testimonial_data['source'];
29
			$link = ( empty( $testimonial_data['link'] ) ) ? '' : $testimonial_data['link'];
30
			$cite = ( $link ) ? '<a href="' . esc_url( $link ) . '" target="_blank">' . $client_name . $source . '</a>' : $client_name . $source;
31
32
			$testimonials .= '<aside class="testimonial">';
33
			$testimonials .= '<span class="quote">&ldquo;</span>';
34
			$testimonials .= '<div class="entry-content">';
35
			$testimonials .= '<p class="testimonial-text">' . get_the_content() . '<span></span></p>';
36
			$testimonials .= '<p class="testimonial-client-name"><cite>' . $cite . '</cite>';
37
			$testimonials .= '</div>';
38
			$testimonials .= '</aside>';
39
40
		endwhile;
41
		wp_reset_postdata();
42
	}
43
44
	return $testimonials;
45
}

Aquí está el CSS que utilizo para aplicar estilo a los testimonios.

1
.testimonial {
2
	padding-left: 60px;
3
	position: relative;
4
	z-index: 0;
5
	font-size: 16px;
6
	}
7
8
	aside.testimonial {
9
10
		}
11
12
	.testimonial .quote {
13
		position: absolute;
14
		left: 0;
15
		top: -25px;
16
		font-size: 300px;
17
		font-family: Georgia, serif;
18
		color: #f2f2f2;
19
		z-index: -1;
20
		line-height: 1;
21
		}
22
23
	.testimonial-text {
24
		font-style: italic;
25
		}
26
27
	.testimonial-client-name {
28
		text-align: right;
29
		font-size: 14px;
30
		}
31
32
		.testimonial-client-name cite {
33
			font-style: normal;
34
			}

Shortcode para los testimonios

Es posible que también desees mostrar testimonios dentro del contenido de tus entradas o páginas. No es un problema. Todo lo que necesitas hacer es conectarte a la API Shortcode de WordPress.

1
add_shortcode( 'testimonial', 'testimonial_shortcode' );
2
/**

3
 * Shortcode to display testimonials

4
 *

5
 * [testimonial posts_per_page="1" orderby="none" testimonial_id=""]

6
 */
7
function testimonial_shortcode( $atts ) {
8
	extract( shortcode_atts( array(
9
		'posts_per_page' => '1',
10
		'orderby' => 'none',
11
		'testimonial_id' => '',
12
	), $atts ) );
13
14
	return get_testimonial( $posts_per_page, $orderby, $testimonial_id );
15
}

Widget de los testimonios

Los widgets son geniales. Son fáciles de usar y pueden añadir mucha funcionalidad en tu sitio. Así que vamos a configurar un sencillo widget de testimonios para que pueda mostrar los testimonios de tus clientes en cualquiera de las áreas de widgets de tu tema.

1
/**

2
 * Testimonials Widget

3
 */
4
class Testimonial_Widget extends WP_Widget {
5
	public function __construct() {
6
		$widget_ops = array( 'classname' => 'testimonial_widget', 'description' => 'Display testimonial post type' );
7
		parent::__construct( 'testimonial_widget', 'Testimonials', $widget_ops );
8
	}
9
10
	public function widget( $args, $instance ) {
11
		extract( $args );
12
		$title = apply_filters( 'widget_title', empty( $instance['title'] ) ? '' : $instance['title'], $instance, $this->id_base );
13
		$posts_per_page = (int) $instance['posts_per_page'];
14
		$orderby = strip_tags( $instance['orderby'] );
15
		$testimonial_id = ( null == $instance['testimonial_id'] ) ? '' : strip_tags( $instance['testimonial_id'] );
16
17
		echo $before_widget;
18
19
		if ( ! empty( $title ) )
20
			echo $before_title . $title . $after_title;
21
22
		echo get_testimonial( $posts_per_page, $orderby, $testimonial_id );
23
24
		echo $after_widget;
25
	}
26
27
	public function update( $new_instance, $old_instance ) {
28
		$instance = $old_instance;
29
		$instance['title'] = strip_tags( $new_instance['title'] );
30
		$instance['posts_per_page'] = (int) $new_instance['posts_per_page'];
31
		$instance['orderby'] = strip_tags( $new_instance['orderby'] );
32
		$instance['testimonial_id'] = ( null == $new_instance['testimonial_id'] ) ? '' : strip_tags( $new_instance['testimonial_id'] );
33
34
		return $instance;
35
	}
36
37
	public function form( $instance ) {
38
		$instance = wp_parse_args( (array) $instance, array( 'title' => '', 'posts_per_page' => '1', 'orderby' => 'none', 'testimonial_id' => null ) );
39
		$title = strip_tags( $instance['title'] );
40
		$posts_per_page = (int) $instance['posts_per_page'];
41
		$orderby = strip_tags( $instance['orderby'] );
42
		$testimonial_id = ( null == $instance['testimonial_id'] ) ? '' : strip_tags( $instance['testimonial_id'] );
43
		?>
44
		<p><label for="<?php echo $this->get_field_id( 'title' ); ?>">Title:</label>
45
		<input class="widefat" id="<?php echo $this->get_field_id( 'title' ); ?>" name="<?php echo $this->get_field_name( 'title' ); ?>" type="text" value="<?php echo esc_attr( $title ); ?>" /></p>
46
47
		<p><label for="<?php echo $this->get_field_id( 'posts_per_page' ); ?>">Number of Testimonials: </label>
48
		<input class="widefat" id="<?php echo $this->get_field_id( 'posts_per_page' ); ?>" name="<?php echo $this->get_field_name( 'posts_per_page' ); ?>" type="text" value="<?php echo esc_attr( $posts_per_page ); ?>" />
49
		</p>
50
51
		<p><label for="<?php echo $this->get_field_id( 'orderby' ); ?>">Order By</label>
52
		<select id="<?php echo $this->get_field_id( 'orderby' ); ?>" name="<?php echo $this->get_field_name( 'orderby' ); ?>">
53
			<option value="none" <?php selected( $orderby, 'none' ); ?>>None</option>
54
			<option value="ID" <?php selected( $orderby, 'ID' ); ?>>ID</option>
55
			<option value="date" <?php selected( $orderby, 'date' ); ?>>Date</option>
56
			<option value="modified" <?php selected( $orderby, 'modified' ); ?>>Modified</option>
57
			<option value="rand" <?php selected( $orderby, 'rand' ); ?>>Random</option>
58
		</select></p>
59
60
		<p><label for="<?php echo $this->get_field_id( 'testimonial_id' ); ?>">Testimonial ID</label>
61
		<input class="widefat" id="<?php echo $this->get_field_id( 'testimonial_id' ); ?>" name="<?php echo $this->get_field_name( 'testimonial_id' ); ?>" type="text" value="<?php echo $testimonial_id; ?>" /></p>
62
		<?php
63
	}
64
}
65
66
add_action( 'widgets_init', 'register_testimonials_widget' );
67
/**

68
 * Register widget

69
 *

70
 * This functions is attached to the 'widgets_init' action hook.

71
 */
72
function register_testimonials_widget() {
73
	register_widget( 'Testimonial_Widget' );
74
}

Plantilla de página de archivo de testimonios

Dado que los testimonios requieren meta personalizado, no puedes confiar en la plantilla de página de archivo predeterminada para mostrarlos correctamente. Para configurar una página de archivo personalizada, necesitas crear un archivo llamado archive-testimonials.php y añadirla a la carpeta principal de tu tema.

1
<?php
2
/**

3
 * Archive template for client testimonials

4
 */
5
6
get_header(); ?>
7
8
	<section id="primary" class="site-content">
9
10
		<div id="content" role="main">
11
			<header class="archive-header">
12
				<h1 class="archive-title">Testimonials</h1>
13
			</header><!-- #archive-header -->
14
15
			<?php while ( have_posts() ) : the_post();
16
				$testimonial_data = get_post_meta( get_the_ID(), '_testimonial', true );
17
				$client_name = ( empty( $testimonial_data['client_name'] ) ) ? '' : $testimonial_data['client_name'];
18
				$source = ( empty( $testimonial_data['source'] ) ) ? '' : ' - ' . $testimonial_data['source'];
19
				$link = ( empty( $testimonial_data['link'] ) ) ? '' : $testimonial_data['link'];
20
				$cite = ( $link ) ? '<a href="' . esc_url( $link ) . '" target="_blank">' . $client_name . $source . '</a>' : $client_name . $source;
21
				?>
22
23
				<article id="post-<?php the_ID(); ?>" <?php post_class( 'testimonial' ); ?>>
24
					<span class="quote">&ldquo;</span>
25
					<div class="entry-content">
26
						<p class="testimonial-text"><?php echo get_the_content(); ?><span></span></p>
27
						<p class="testimonial-client-name"><cite><?php echo $cite; ?></cite></p>
28
					</div>
29
				</article>
30
31
			<?php endwhile; ?>
32
33
			<?php
34
			global $wp_query;
35
36
			if (  1 < $wp_query->max_num_pages ) : ?>
37
				<nav class="archive-navigation" role="navigation">
38
					<div class="nav-previous alignleft"><?php next_posts_link( '<span class="meta-nav">&larr;</span> Older posts' ); ?></div>
39
					<div class="nav-next alignright"><?php previous_posts_link( 'Newer posts <span class="meta-nav">&rarr;</span>' ); ?></div>
40
				</nav><!-- .archive-navigation -->
41
				<?php
42
			endif;
43
			?>
44
		</div>
45
46
	</section><!-- #primary -->
47
48
<?php get_sidebar(); ?>
49
<?php get_footer(); ?>

Conclusión

Esperamos que no te hayas sentido demasiado abrumado por la cantidad de código presentado. Es posible que no tengas que usarlo todo, ya que realmente depende de cuáles sean tus necesidades. Es posible que solo necesites el shortcode o simplemente la plantilla de archivo. De cualquier manera, este tutorial te debería preparar para muchas situaciones con las que te puedes encontrar al añadir testimonios de clientes en tu sitio.

Si tienes algún comentario u opinión sobre cualquier cosa que hayas leído más arriba, no dudes en debatirlo a continuación.