Obtener la URL del Thumbnail de un Post

1
2
3
4
5
6
7
8
9
10
11
$thumbnail_id   = get_post_thumbnail_id();
$thumbnail_data = wp_get_attachment_image_src($thumbnail_id,'thumbnail', true);
$thumbnail_url  = $thumbnail_data[0]; 
 
/*
Devuelve un array con los siguientes valores:
 [0] => url de la imagen,
 [1] => ancho de la imagen, 
 [2] => alto de la imagen, 
 [3] => escala
*/

http://codex.wordpress.org/Function_Reference/wp_get_attachment_image_src

Limitar colres de texto en TinyMCE

function my_mce_settings( $settings ) {
 
  //limita los colores de texto en TinyMCE para sólo tener algunos colores predefinidos
  $custom_colors = '"43a9cf", "Azul", "dfa10d", "Naranja", "be7bd2", "Violeta"';    
  $settings['textcolor_map'] = '['.$custom_colors.']';
 
  return $settings;
}
add_filter('tiny_mce_before_init', 'my_mce_settings');

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 modificar la lista de provincias para envios en WooCommerce

A través del filtro woocommerce_states que devuelve un array de estados o provincias podemos modificar la lista a nuestro antojo, simplemente añadiendo unas líneas de código en nuestro plugin o el archivo functions.php de nuestro theme.

Para los ejemplos que voy a poner aquí vamos a suponer que en los ajustes de WooCommerce hemos seleccionado España como país para los envíos.

add_filter('woocommerce_states', 'my_custom_states');
 
function my_custom_states( $states ) {
 
   // aquí el código para modificar el array $states
   return $states;
}

Por ejemplo si no realizaramos envios a Canarias, podemos eliminar la opción Santa Cruz de Tenerife del array de provincias de esta manera:

add_filter('woocommerce_states', 'my_custom_states');
 
function my_custom_states( $states ) {
 
   unset($states['ES']['TF']);
   return $states;
}

Para excluir una lista de provincias:

add_filter('woocommerce_states', 'my_custom_states');
 
function my_custom_states( $states ) {
 
	$exclude = array('TF','BU','SG','ML','NA','OR');
 
	foreach( $exclude as $item ) {
		unset($states['ES'][$item]);
	}
 
	return $states;
}

O si sólo realizamos envíos a 3 provincias:

add_filter('woocommerce_states', 'my_custom_states');
 
function my_custom_states( $states ) {
 
   $states = array(
     'B'  => 'Barcelona',
     'MU' => 'Murcia',
     'SG' => 'Segovia'
   );
 
   return $states;
}

Puedes encontrar toda la lista de provincias y sus códigos dentro del plugin de WooCommerce, esta es la ruta a dicho archivo: woocommerce/i18n/states/ES.php (junto con el resto de archivos para los demás países)

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”.

Eliminar las notificaciones por correo de WooCommerce

Snippet útil por Mike Jolley encontrado en Github con una lista de hooks para las notificaciones de WooCommerce.

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_action( 'woocommerce_email', 'unhook_those_pesky_emails' );
 
function unhook_those_pesky_emails( $email_class ) {
 
		/**
		 * Hooks for sending emails during store events
		 **/
		remove_action( 'woocommerce_low_stock_notification', array( $email_class, 'low_stock' ) );
		remove_action( 'woocommerce_no_stock_notification', array( $email_class, 'no_stock' ) );
		remove_action( 'woocommerce_product_on_backorder_notification', array( $email_class, 'backorder' ) );
 
		// New order emails
		remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class-&gt;emails['WC_Email_New_Order'], 'trigger' ) );
		remove_action( 'woocommerce_order_status_pending_to_completed_notification', array( $email_class-&gt;emails['WC_Email_New_Order'], 'trigger' ) );
		remove_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $email_class-&gt;emails['WC_Email_New_Order'], 'trigger' ) );
		remove_action( 'woocommerce_order_status_failed_to_processing_notification', array( $email_class-&gt;emails['WC_Email_New_Order'], 'trigger' ) );
		remove_action( 'woocommerce_order_status_failed_to_completed_notification', array( $email_class-&gt;emails['WC_Email_New_Order'], 'trigger' ) );
		remove_action( 'woocommerce_order_status_failed_to_on-hold_notification', array( $email_class-&gt;emails['WC_Email_New_Order'], 'trigger' ) );
 
		// Processing order emails
		remove_action( 'woocommerce_order_status_pending_to_processing_notification', array( $email_class-&gt;emails['WC_Email_Customer_Processing_Order'], 'trigger' ) );
		remove_action( 'woocommerce_order_status_pending_to_on-hold_notification', array( $email_class-&gt;emails['WC_Email_Customer_Processing_Order'], 'trigger' ) );
 
		// Completed order emails
		remove_action( 'woocommerce_order_status_completed_notification', array( $email_class-&gt;emails['WC_Email_Customer_Completed_Order'], 'trigger' ) );
 
		// Note emails
		remove_action( 'woocommerce_new_customer_note_notification', array( $email_class-&gt;emails['WC_Email_Customer_Note'], 'trigger' ) );
}

Como obtener el “slug” de un post

basename( get_permalink($id) );

Si tienes disponible los datos del post en la variable global $post puedes simplemente usar $post->post_name;

1
2
3
4
5
6
7
8
9
10
11
12
function get_slug( $id = NULL ) {
 
   if( $id != NULL ) {
     return basename( get_permalink($id) );
   }
 
   global $post;
   if( empty($post) ) return;
 
   return $post->post_name;
 
}

En otros casos puede que no tengas el $id y estes intentando recuperar $post demasiado pronto como por ejemplo en el hook init donde los datos del post aún no estan disponibles. En este caso puedes intentar usar la función url_to_postid para recuperar el ID y luego poder tener el slug.

La función completa quedaría de la siguiente manera:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
function get_slug( $id = NULL ) {
 
  if( $id == NULL ){
 
    global $post;
 
   if( !empty( $post )) {
        $id = $post->ID;
    } else {
        $id = url_to_postid( "http://".$_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
    }
 
  } // if $id NULL
 
  return basename( get_permalink($id) );
}

Contact Form 7, guardar formulario en la base de datos

Crear la tabla para guardar los datos en la base de datos.

CREATE TABLE `wp_tps_forms` (
  `id` int(11) unsigned NOT NULL AUTO_INCREMENT,
  `form` varchar(100) NOT NULL DEFAULT '',
  `data` text NOT NULL,
  `date` datetime NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;

Llamar la función justo antes del envío de correo con el hook wpcf7_before_send_mail.

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
 
add_action('wpcf7_before_send_mail', 'save_form' );
 
function save_form( $wpcf7 ) {
   global $wpdb;
 
   /*
    Nota: desde la version 3.9 Contact Form 7 ha eliminado $wpcf7->posted_data
    y ahora se accede a los datos a través de API.
   */
 
   $submission = WPCF7_Submission::get_instance();
 
   if ( $submission ) {
 
       $submited = array();
       $submited['title'] = $wpcf7->title();
       $submited['posted_data'] = $submission->get_posted_data();
 
    }
 
     $data = array(
   		'name'  => $submited['posted_data']['name'],
   		'email' => $submited['posted_data']['email']
   	     );
 
     $wpdb->insert( $wpdb->prefix . 'tps_forms', 
		    array( 
                          'form'  => $submited['title'], 
			   'data' => serialize( $data ),
			   'date' => date('Y-m-d H:i:s')
			)
		);
}

Contact Form 7, cambiar textos en el cuerpo del email

Por ejemplo, supongamos que recibes el ID de un POST como parámetro, y quieres añadir el título del post en el cuerpo del email enviado con el plugin Contact Form 7.
Puedes añadir el texto [my_post_id] en el cuerpo del mensaje desde la pantalla de configuración del formulario en el panel de administración. Y después reemplazar este texto con la información que necesitas, en este caso el tíutlo del post, usando el filter wpcf7_mail_components.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
add_filter( 'wpcf7_mail_components', 'custom_mail_components');
 
function custom_mail_components($wpcf7_data, $form = null) {
 
     if( isset( $_GET['my_post_id'] ) ){
 
        $post = get_post( $_GET['my_post_id'], ARRAY_A );
 
        $str = $post['post_title']. ' ' . get_permalink( $_GET['my_post_id'] ) ;
	$wpcf7_data['body'] = str_replace('[my_post_id]', $str , $wpcf7_data['body'] );
     }
 
     return $wpcf7_data;
}