Set “Envelope-From” header for wp_mail()

WordPress emails were not being sent out by the server. But why?
In this case the site is hosted by Goneo.
As it appears Goneo requires:

  1. Emails to be sent from an address registered with them
  2. The ‘Envelope-From’ email header set to that address

It’s not a bug, it’s a feature!

Set the thing…

WordPress sends its emails via the wp_mail() function. In turn, this function uses the PHPMailer library to generate and send the actual email. Just before sending the mail, wp_mail() calls the helpful phpmailer_init action which gives us access to the PHPMailer instance. This is where we can use the setfrom() method to set the Envelope From header:

add_action( 'phpmailer_init', 'prefix_add_phpmailer_setfrom' );

/**
 * Add setFrom for hosts that insist on making life hard.
 *
 * @param array $phpmailer The PHPMailer instance, passed by reference.
 */
function prefix_add_phpmailer_setfrom( $phpmailer ) {

	$phpmailer->setFrom(
		get_option( 'admin_email' ), // From email address.
		'WordPress' // From name.
	);
}

Rejoice!

Fluid text (or any other property) size depending on screen width

Responsive text styles depending on screen size is all the rage these days.
Here’s an example of a sass mixin that lets you define a screen width where a max value should be reached, and the smallest value it is allowed to have. It will interpolate between these values automatically.

/**
 * Interpolate a value down to a minimum value from its
 * maximum at a defined viewport width
 *
 * @param {string} $property           The css attribute, eg. 'font-size'
 * @param {int}    $value_min          Minimum value in pixels.
 * @param {int}    $value_max          Minimum value in pixels.
 * @param {int}    $viewport_width_max Viewport width for the max value.
 */
@mixin vw-min-max( $property, $value_min, $value_max, $viewport_width_max ) {

	$vw: ( $value_max / $viewport_width_max ) * 100;
	$min_width: ( $value_min / $vw ) * 100;
	$mq_min: #{$min_width}px;
	$mq_max: #{$viewport_width_max}px;

	#{$property}: #{$value_min}px;
	@media all and (min-width: $mq_min) {
		#{$property}: #{$vw}vw;
	}
	@media all and (min-width: $mq_max) {
		#{$property}: #{$value_max}px;
	}
}

For example: A header should have a font-size of 80px at 1000px wide, and grow smaller on narrower screens, but not smaller than 20px.

h2 {
	@include vw-min-max( 'font-size', 20, 80, 1000 );
}

See it in use on my portfolio site, where it is applied not only to text, but also various divs to create a fluid appearance on window resize.

Save a Custom Meta Boxes plugin Taxonomy Select Field as a term for a post

The helpful Custom Meta Boxes plugin by Human Made provides a Taxonomy Select Field. Ever so sneakily, instead of adding the post to the selected term as one might expect, the plugin saves the taxonomy term id in a custom field. Let’s fix that. Continue reading “Save a Custom Meta Boxes plugin Taxonomy Select Field as a term for a post”

Add “virtual” page templates in WordPress

A super nifty feature was added to WordPress 4.4: the possibility to dynamically add page templates (#34995).

Previously a theme author would need to add actual custom page template files to their theme. The template would then show up in the Template dropdown of the Page Attributes meta box.

Theme and plugin authors can now add page templates to the Template dropdown by adding a 'name' => 'Title' entry to the list of templates via the theme_page_templates filter.

Add an entry to the page template dropdown

/**
 * Add an entry to the page templates dropdown.
 *
 * This function hooks into the 'theme_page_templates' filter which is
 * documented in wp-includes/class-wp-theme.php.
 *
 * @param array $page_templates  Array of page templates. Keys are filenames,
 *                               values are translated names.
 * @return array Array of page templates including our custom ones.
 */
function prefix_filter_page_templates( $page_templates ) {

	/*
	 * Add an entry to the $page_templates array.
	 * Prefixing the key might be a good idea as
	 * an entry with that key might already exist.
	 */
	$page_templates['prefix_example_template'] = __( 'Example Template', 'textdomain' );

	return $page_templates;
}
add_filter( 'theme_page_templates', 'prefix_filter_page_templates' );

You can find out which template is assigned to a page with the get_page_template_slug( $post ); function.

So what?

A plugin might want to add a page template which adds something to the post content. Perhaps a calendar page template, or a price list page template.

/**
 * Add something to the post content.
 *
 * If the 'prefix_example_template' is selected,
 * add stuff below the post content.
 *
 * @since 1.0.0
 * @param string $content Post content.
 * @return string
 */
function prefix_add_stuff_to_content( $content ) {

	if ( ! is_admin() && is_page() ) {

		$template_slug = get_page_template_slug( $post->ID );

		if ( 'prefix_example_template' === $template_slug ) {
			$content = 'Stuff I want to add goes here' . $content;
		}
	}
	
	return $content;
}
add_filter( 'the_content', 'prefix_add_stuff_to_content' );

Maybe a page with our “Example Template” will not need the text editor in the admin.

/**
 * Remove TinyMCE editor if the 'Example Template' is selected/
 */
function prefix_maybe_remove_editor_support() {

	if ( empty( $_GET['post'] ) ) {
		return;
	}

	$post = get_post( absint( $_GET['post'] ) );

	if ( ! $post ) {
		return;
	}

	$post_type = get_post_type( $_post );

	if ( 'page' !== $post_type ) {
		return;
	}

	if ( 'prefix_example' === get_page_template_slug( $post ) ) {
		remove_post_type_support( 'page', 'editor' );
	}
}
add_action( 'load-post.php', 'prefix_maybe_remove_editor_support' );

Or we might want to add a meta box to the page edit screen if our page template is selected.

/**
 * Add a meta box to the page edit screen if the `prefix_example_template`
 * page template is selected for the page in question.
 */
function prefix_maybe_add_my_cool_meta_box( $post_type, $post ) {
	
	if ( 'page' !== $post_type ) {
		return;
	}

	if ( 'prefix_example_template' !== get_page_template_slug( $post->ID ) ) {
		return;	
	}

	add_meta_box(
		'example-meta-box',
		esc_html__( 'My Cool Meta Box', 'textdomain' ),
		'callback',
		'page',
		'normal',
		'high'
	);
}
add_action( 'add_meta_boxes', 'prefix_maybe_add_my_cool_meta_box', 10, 2 );

Okay, the last two examples are not specifically related to the new “virtual” page templates. I hoped to illustrate some stuff you can do with them.

I’ve been happily using this in my projects (even if frowned upon) to dynamically add page templates for use as archive pages for custom post types. Neat for vanity URLs!