Load scripts only when needed in the WordPress admin

Lets say we are creating a plugin witch needs to load a javascript file on it’s settings page, we would only want to load the file on that specific page and not in every other admin page.

To do so, we can declare a global variable while creating the settings page so we can know exactly when we need to load our js file.

1. Create the settings page for the 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. Make the call checking the global variable $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' );
 
/*
To call the script in other WordPress pages, for example the edit page of a post: 
 
if( $hook != 'edit.php' ) return;
 
Other pages:
- Dashboard: index.php
- Media library: upload.php
- Comments: edit-comments.php
- Edit a comment: comment.php
- Appearance: themes.php
- Widgets: widgets.php
- Menus: nav-menus.php
- Plugins: plugins.php
- Users: users.php
- General Settings: options-general.php
*/

More information:
http://codex.wordpress.org/Plugin_API/Action_Reference/admin_enqueue_scripts

Add meta box to a custom post type

Before adding a metabox to a custom post type we need to create the custom post type.
Check this post where you can find a full class to create your custom post type.

So following on this example our custom post type is cpt_examples.

In the __construct function of our custom post type class add the following:

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

And then create the functions in the class.

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
 * function called on save_post hook to sanitize and save the data
 */
 
public function save_meta_box_data( $post_id ){
 
  // Check if nonce is set.
    if ( ! isset( $_POST['cptexamples_meta_box_nonce'] ) ) {
	  return;
    }
 
  // Verify that the nonce is valid.
    if ( ! wp_verify_nonce( $_POST['cptexamples_meta_box_nonce'], 'cptexamples_meta_box' ) ) {
	   return;
    }
 
  // If autosave, don't do anything
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
	  return;
    }
 
  // Check the user's permissions.
    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;
	    }
    }
 
   // Save the information into the database
       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 );
	}
 
 
}

Also view this snippet to add the meta box just after the title.

Create custom post type from a plugin

The Class file

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
<?php 
/** 
 * @package    WPtips
 * @subpackage Custom Post Type Example
 * @author     Lucy Tomás
 * @since      1.0
 */
 
// Exit if accessed directly
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' => $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'   => 'Basic help CPT Examples',
			'content' => '<p>From this section you can view a list of CPT Examples.</p>
                                      <p>Click on one of them to Edit or click on Add New to create a new one.</p>'
		);
 
		$formatting = array(
			'id'      => 'cpt_examples_formating',
			'title'   => 'Creation of a CPT Example',
			'content' => '<p>Fill in the form with title and text .</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
 
}

You can see on this other post how to add Meta Boxes with extra form fields for this custom post type class.

Remove WooCommerce email notifications

Useful snippet by Mike Jolley found on Github with a list of the notification hooks in 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' ) );
}

How to get the post slug

basename( get_permalink($id) );

If you have access to the data through the global variable $post you can simply use $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;
 
}

In other cases maybe you don’t have the $id and you are trying to get the $post var to early like in an init hook, in this case you can try using url_to_postid to retrieve the ID and then get the slug.

So the full function would be:

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, save submited data in the database

Create a table to store the data in the database.

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;
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;
 
   /*
    Note: since version 3.9 Contact Form 7 has removed $wpcf7->posted_data
    and now we use an API to get the posted data.
   */
 
   $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, change texts on email body

For example, you receive a POST ID as a parameter, and you want to add the title of the post in the body of the email sent by Contact Form 7.
You can add the text [my_post_id] in the body of the form configuration from the admin dashboard.
Then replace it with the data you need, in this case the title, using the filer 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;
}

Move meta box after the title

First register your meta box with $context ‘advanced’ and $priority ‘high’

1
add_meta_box( 'my_metabox_id', 'my_metabox_title', 'my_callback', 'post_type', 'advanced', 'high' );

Then use the hook edit_form_after_title to print the metaboxes with do_meta_boxes function and unset them so they don’t display twice. It will move all metaboxes on the screen with an advanced context.

1
2
3
4
5
6
7
8
add_action('edit_form_after_title',  array( $this, 'move_metabox_after_title' ) );
 
function move_metabox_after_title () {
    global $post, $wp_meta_boxes;
 
    do_meta_boxes( get_current_screen(), 'advanced', $post );
    unset( $wp_meta_boxes[get_post_type( $post )]['advanced'] );
}

Source found here.

Add Walker_Nav_Menu extension with Genesis

1
2
3
4
5
6
7
8
9
10
11
12
// filer wp_nav_menu_args to add the custom walker to wp_nav_menu(), used by genesis_do_nav()
add_filter( 'wp_nav_menu_args', 'my_navigation_walker' );
 
function my_navigation_walker ( $args ){
    if( isset( $args['menu_class'] ) && 'menu genesis-nav-menu menu-primary' === $args['menu_class'] ) {
	if( class_exists( 'My_Navigation' ) ) {
		$args['walker'] = new My_Navigation(); 
	}
    }
 
    return $args;
 }

Source found here

Create Sitemap HTML Page

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
<?php 
 
 /*
 Template Name: Sitemap Page
 */
 
get_header();
 
	/* PAGES
	----------------------------------------------*/
 
	// Get the navigation items to display the same order and save them in array to exclude later
 
	$items = wp_get_nav_menu_items( 'my menu id' );
	$exclude_pages = get_the_ID(); // to not display current sitemap page
 
	echo '<ul>';
 
 	foreach( $items as $item )  {
 
                $class = '';
		$exclude_pages .= ',' . $item->object_id;
 
		if( $item->menu_item_parent != 0) {
			$class = ' class="sitemap-item-child"';
		}
 
		?>
			<li<?php echo $class ?>>
				<a href=""><?php echo $item->title; ?></a>
			</li>
 
		<?php
 
	}
 
	// List the rest of the pages that are not in the navigation
	wp_list_pages(
			 array(
			   'exclude' => $exclude_pages,
			   'title_li' => '',
			 )
		);
 
	echo '</ul>';
 
	/* CUSTOM POST TYPES 
	----------------------------------------------*/
 
	foreach( get_post_types( array('public' => true) ) as $post_type ) {
 
	  if ( in_array( $post_type, array('post','page','attachment') ) ) continue;
 
	  $item = get_post_type_object( $post_type );
 
	  echo '<h2>'.$item->labels->name.'</h2>';
 
	  $args = array(
		'post_type' => $post_type,
		'posts_per_page'    => -1
	  );
 
	  $query = new WP_Query( $args );
 
	  echo '<ul>';
 
		while ( $query->have_posts() ) {
 
			$query->the_post();
			echo '<li><a href="'.get_permalink().'">'.get_the_title().'</a></li>';
 
		}
 
	  echo '</ul>';
 
	}
 
 
get_footer();