Recursos y Herramientas para desarrollo WordPress

Puede que esta lista crezca o cambie con el tiempo.

GitHub updater
Plugin para permitir actualizaciones automáticas a tus plugins o themes alojados en GitHub o Bitbucket
https://github.com/afragen/github-updater

Developer
Plugin que te permitirá optimizar tu entorno de trabajo asegurándose de que tienes todos las herramientas esenciales y plugins instalados.
https://wordpress.org/plugins/developer/

Theme Check
Comprueba que el Theme sigue los últimos estándares y buenas prácticas de WordPress.
https://wordpress.org/plugins/theme-check/

Log Deprecated Notices
Hace un log del uso de archivos, funciones argumentos de funciones obsoletas. Identifica el lugar en las que estan siendo usadas y ofrece una alternativa si existe. También identifica el uso incorrecto de las funciones.
https://wordpress.org/plugins/log-deprecated-notices/

Monster Widget
Ofrece un método rápido y fácil para añadir todos los widgets del core en el sidebar para testear.
https://wordpress.org/plugins/monster-widget/

Debug Bar
El plugin añade un menu debug en la barra de administrador para mostrar información útil para la depuración de errores.
https://wordpress.org/plugins/debug-bar/

Lista de herramientas de validación de código
http://codex.wordpress.org/Validating_a_Website#HTML_-_Validation

Theme Framework: Hybrid Core
Esto no es un “parent theme”. Es un framework para crear tu propio theme.
https://github.com/justintadlock/hybrid-core

WP Test
Iportar contenido de ejemplo para test. El contenido contiene diferentes estilos, listas, mágenes flotantes, etc… para ver como reacciona todo tipo de contenido en el theme.
http://wptest.io/

Cargar javascript en el admin de WordPress sólo cuando se necesita

Supongamos que estamos desarrollando un plugin que necesita carga un archivo javascript en su página de ajustes, sólo necesitaríamos hacer la llamada del script para esa página en concreto y no en el resto de secciones del admin.

Para hacer esto podemos declarar una variable global a la hora de crear la página de ajustes, de ese modo podemos saber exáctamente cuando necesitamos cargar el script.

1. Crea la página de ajustes del plugin.

 
function my_settings_page (){
 
     global $my_settings_page;
 
     $my_settings_page = add_options_page( __('My Settings', 'my-domain'), 
                                           __('Settings', 'my-domain'), 
	 			           'manage_options', 
                                           'my-page-slug', 
	 				   'my-callback'
	 				 );
}
 
add_action( 'admin_menu', 'my_settings_page');

2. Haz la llamada en función del valor de la variable global $my_settings_page;

 
function my_admin_script( $hook ) {
 
    global $my_settings_page;
 
    if( $hook != $my_settings_page ) return;
 
    wp_enqueue_script( 'my-admin-script', MY_PLUGIN_URL . 'js/my-script.js');
}
 
add_action( 'admin_enqueue_scripts', 'my_admin_script' );
 
/*
Para cargar el script en otra de las páginas de WordPress, por ejemplo al editar un post:
 
if( $hook != 'edit.php' ) return;
 
Otras páginas:
- Escritorio: index.php
- Librería de medios: upload.php
- Comentarios: edit-comments.php
- Editar comentario: comment.php
- Apariencia: themes.php
- Widgets: widgets.php
- Menus: nav-menus.php
- Plugins: plugins.php
- Usuarios: users.php
- Ajustes generales: options-general.php
*/

Más información:
http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts

Como cargar plantillas desde un plugin

Los archivos de plantillas (templates) se usan comunmente en themes y child themes, pero también puedes cargar estos archivos desde un plugin.

No es demasiado complicado crear tu propio cargador de plantillas, pero puedes encontrar una clase en GitHub creada por Gary Jones, Gamajo_Template_Loader

Para usar esta clase:
1. Crea un archivo dentro de tu plugin y copia la clase Gamajo_Template_Loader.
2. Crea una subclase de Gamajo_Template_Loader. Aquí tienes un ejemplo de esta subclase
3. Sobreescribe las propiedades de la clase para que se ajusten a tu plugin, dichas propiedades son : $filter_prefix, $theme_template_directory, $plugin_directory.

También puedes encontrar un ejemplo de un plugin completo utilizando Gamajo_Template_Loader creado por Pippin Williamson de pippinsplugins.com

Añadir meta box a un “custom post type”

Antes de añadir un meta box a un “custom post type” necesitamos crear un custom post type.
Echa un vistazo a esta clase completa para crear un custom post type desde un plugin.

Así que siguinedo con este ejemplo nuestro custom post type es cpt_examples

En la función constructora __construct de nuestra clase para crear custom post type añade las siguientes líneas:

1
2
add_action( 'add_meta_boxes', array( $this, 'add_meta_box') );
add_action( 'save_post',      array( $this, 'save_meta_box_data' ) );

Y después crea las funciones en la clase.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
/**
 * add_meta_box
 */
public function add_meta_box(){
 
	add_meta_box( 'cpt_examples_meta', 'CPT Examples Extra Info', array( $this, 'display_meta_form' ), 'cpt_examples', 'advanced', 'high' );
}
 
/**
 * display_meta_form	
 */
 
public function display_meta_form( $post ) {
 
	wp_nonce_field( 'cptexamples_meta_box', 'cptexamples_meta_box_nonce' );
 
	$my_first_field  = get_post_meta( $post->ID, 'cpt_first_meta_field', true );
	$my_second_field = get_post_meta( $post->ID, 'cpt_second_meta_field', true );
 
		echo '<div class="wrap">';
		echo '<label for="cpt_first_meta_field">' . _e( 'First Meta Field', 'cpt_domain' ) . '</label> <br/>';
		echo '<input class="text" type="text" id="cpt_first_meta_field" name="cpt_first_meta_field" value="' . esc_attr( $my_first_field ) . '"   />';
		echo '</div>';
 
		echo '<div class="wrap">';
		echo '<label for="cpt_second_meta_field">' . _e( 'Second Meta Field', 'cpt_domain' ) . '</label>  <br/>';
		echo '<input class="text" type="text" id="cpt_second_meta_field" name="cpt_second_meta_field" value="' . esc_attr( $my_second_field ) . '"   />';
		echo '</div>';
}
1
2
3
4
5
6
7
8
9
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
/**
 * save_meta_box_data
 * función llamada en el hook save_post para validar y guardar los datos.
 */
 
public function save_meta_box_data( $post_id ){
 
  // Verificar que se ha declarado el nonce.
    if ( ! isset( $_POST['cptexamples_meta_box_nonce'] ) ) {
	  return;
    }
 
  // Verificar que el nonce es válido.
    if ( ! wp_verify_nonce( $_POST['cptexamples_meta_box_nonce'], 'cptexamples_meta_box' ) ) {
	   return;
    }
 
  // Si es un autoguardado no debe hacer nada.
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
	  return;
    }
 
  // Verificar los permisos del usuario.
    if ( isset( $_POST['post_type'] ) && $_POST['post_type'] == 'cpt_examples' ) {
            if ( ! current_user_can( 'edit_page', $post_id ) ) {
		     return;
	    }
 
    } else {
            if ( ! current_user_can( 'edit_post', $post_id ) ) {
		     return;
	    }
    }
 
   // Guardar la información en la base de datos
       if ( isset( $_POST['cpt_first_meta_field'] ) ) {
 
             $my_first_meta_field = sanitize_text_field( $_POST['cpt_first_meta_field'] );
	     update_post_meta( $post_id, 'cpt_first_meta_field', $my_first_meta_field );
	}
 
       if ( isset( $_POST['cpt_second_meta_field'] ) ) {
 
             $my_second_meta_field = sanitize_text_field( $_POST['cpt_second_meta_field'] );
	     update_post_meta( $post_id, 'cpt_second_meta_field', $my_second_meta_field );
	}
 
 
}

También visita este otro snippet para posicionar el metabox justo después del título dentro del formulario.

Crear “custom post type” desde un plugin

La clase.

1
2
3
4
5
6
7
8
9
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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php 
/** 
 * @package    WPtips
 * @subpackage Ejemplo Custom Post Type 
 * @author     Lucy Tomás
 * @since      1.0
 */
 
// Exit si se accede directamente
if ( !defined( 'ABSPATH' ) ) exit;
 
 
if( !class_exists( 'CPT_Example' )){
 
class CPT_Example {
 
	/**
	 * constructor
	 * @since 1.0
	 */
 
	public function __construct() {
 
		add_action( 'init', 		     array( $this, 'register_posttype'));
		add_filter( 'post_updated_messages', array( $this, 'custom_post_type_messages'));
		add_action( 'admin_head',            array( $this, 'custom_post_type_help' ) );
		add_filter( 'template_include',      array( $this, 'post_type_template'));
 
	}	
 
	/**
	 * register_posttype
	 * @since 1.0
	 */
 
	public function register_posttype() {
 
		$labels = array(
					'name'               => __('CPT Examples', 'cpt_domain'),
					'singular_name'      => __('CPT Example', 'cpt_domain'),
					'menu_name'          => __('CPT Examples', 'cpt_domain'),
					'name_admin_bar'     => __('CPT Example', 'cpt_domain'),
					'add_new'            => __('Add new', 'cpt_domain'),
					'add_new_item'       => __('Add new CPT Example', 'cpt_domain'),
					'new_item'           => __('New CPT Example', 'cpt_domain'),
					'edit_item'          => __('Edit CPT Example', 'cpt_domain'),
					'view_item'          => __('View CPT Examples', 'cpt_domain'),
					'all_items'          => __('All CPT Examples', 'cpt_domain'),
					'search_items'       => __('Search CPT Examples', 'cpt_domain'),
					'parent_item_colon'  => __('CPT Example parent', 'cpt_domain'),
					'not_found'          => __('No CPT Example found', 'cpt_domain'),
					'not_found_in_trash' => __('No CPT Example in trash', 'cpt_domain')
		);
 
 
		$slug = get_theme_mod( 'ctp_example_permalink' );
  		$slug = ( empty( $slug ) ) ? 'cpt-example' : $slug;
 
 
 		$args = array( 
			'public'        => true, 
			'labels'        => $labels,
			'description'   => __('CPT Examples', 'cpt_domain'),
			'menu_icon'     => 'dashicons-groups',
			'menu_position' => 5,
			'has_archive' 	=> true,
			'supports'      => array( 'title', 'editor', 'thumbnail'),
			'rewrite'     	=> array( 'slug' =&gt; $slug )
 
		);
 
		register_post_type( 'cpt_examples', $args );
 
	}
 
	/**
	 * custom_post_type_messages
	 * @since 1.0
	 */
 
	public function custom_post_type_messages( $messages ) {
 
		$post = get_post();
 
			$messages['cpt_examples'] = array(
				0  => '',
				1  => __('CTP Example updated', 'cpt_domain'),
				2  => __('Custom field updated', 'cpt_domain'),
				3  => __('Custom field deleted', 'cpt_domain'),
				4  => __('CTP Example updated', 'cpt_domain'),
				5  => isset( $_GET['revision'] ) ? sprintf( __('CTP Example restored to revision', 'cpt_domain') . ' %s',wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
				6  => __('CTP Example published', 'cpt_domain'),
				7  => __('CTP Example saved', 'cpt_domain'),
				8  => __('CTP Example sent', 'cpt_domain'),
				9  => sprintf(
					__('CTP Example programed for', 'cpt_domain') . ': <strong>%1$s</strong>.',
					date_i18n( 'M j, Y @ G:i', strtotime( $post->post_date ) )
				),
				10 => __('Draft CTP Example updated', 'cpt_domain')
			);
 
 
		return $messages;
 
	}
 
	/**
	 * custom_post_type_help
	 * @since 1.0
	 */
 
	public function custom_post_type_help() {
 
 
		$screen = get_current_screen();
 
		if ( $screen->post_type != 'cpt_examples' ) {
			return;
		}
 
		$basics = array(
			'id'      => 'cpt_examples_basics',
			'title'   => 'Ayuda básica para CPT',
			'content' => '<p>Desde esta sección puedes visualizar una lista de CPT Ejemplos.</p>
                                      <p>Haz click en una para Editar o haz click en Añadir Nuevo para crear una nueva.</p>'
		);
 
		$formatting = array(
			'id'      => 'cpt_examples_formating',
			'title'   => 'Creación de un CPT Ejemplo',
			'content' => '<p>Rellena el frmulario para crear un nuevo CPT Ejemplo .</p>'
 
		);
 
		$screen->add_help_tab( $basics );
		$screen->add_help_tab( $formatting );
 
 	}
 
	/**
	 * post_type_template
	 * @since 1.0
	 */
 
	function post_type_template( $original_template ) {
 
 
		  if ( is_post_type_archive('cpt_examples') ) {
 
		    load_template( plugin_dir_path( __FILE__ ) . 'templates/cpt_examples.php');
 
		  } else {
 
		    return $original_template;
		  }
 
	}
 
 
 
}// class
 
}

En esta otra entrada puedes ver como añadir meta box con campos de formulario extra a esta misma clase de “custom post type”.