Change the WordPress Password Protected Message

When you password protect a post or page in WordPress, visitors see a fixed message above the password field. This snippet changes the WordPress password protected message to your own text, can add a link where people request the password, or removes the message completely.

It works whatever language the site is in and whichever wording your WordPress version uses, because it does not search for the English sentence.

The snippet

<?php
/**
 * Change the message above the WordPress password form on protected posts and pages.
 */

// ===== Config =====
function dpc_password_message_config() {
	$config = array(
		// Text above the password field. Empty '' (and no link) removes the paragraph.
		'message'   => __( 'This content is password protected. Enter the password below, or request one if you do not have it.', 'dpc' ),
		// Optional link after the text, e.g. your contact page: home_url( '/request-password/' ). Empty '' = no link.
		'link_url'  => '',
		'link_text' => __( 'Request a password', 'dpc' ),
	);
	// ===== End of config =====

	return (array) apply_filters( 'dpc_password_message_config', $config );
}

add_filter( 'the_password_form', 'dpc_password_message', 10, 2 );

function dpc_password_message( $output, $post = null ) {
	$config = wp_parse_args(
		dpc_password_message_config(),
		array( 'message' => '', 'link_url' => '', 'link_text' => '' )
	);

	$html = esc_html( $config['message'] );
	$url  = esc_url( $config['link_url'] );
	if ( '' !== $url && '' !== $config['link_text'] ) {
		$html .= ( '' === $html ? '' : ' ' ) . sprintf(
			'<a class="dpc-password-request" href="%1$s">%2$s</a>',
			$url,
			esc_html( $config['link_text'] )
		);
	}
	$html = (string) apply_filters( 'dpc_password_message_html', $html, $post );

	// The intro is the first plain <p> without a form field, whatever language or wording WordPress uses.
	return (string) preg_replace_callback(
		'#<p>((?:(?!</p>).)*)</p>\s*#s',
		function ( $m ) use ( $html ) {
			if ( false !== stripos( $m[1], '<input' ) ) {
				return $m[0];
			}
			return '' === $html ? '' : '<p class="dpc-password-message">' . $html . '</p>';
		},
		$output,
		1
	);
}

How it works

  • WordPress builds the form in get_the_password_form() and passes the HTML through the the_password_form filter. The intro text is the first plain <p> in that form; the next one holds the field and the button.
  • The snippet replaces the first <p> that has no <input> in it with your message. The field, the button, the hidden redirect_to and the invalid password notice stay as WordPress made them.
  • Searching for the English text breaks on translated sites, and it also broke when WordPress reworded the sentence (“password-protected”, with a hyphen). Matching the paragraph avoids both.
  • The message goes through esc_html(), the URL through esc_url(). A URL that esc_url() rejects, such as javascript:, gives no link at all.
  • There are no inline styles. The paragraph has the class dpc-password-message and the link dpc-password-request.

Add it with Scripts Organizer

In Scripts Organizer go to Code Blocks → Add New and give the block a name. Set Trigger location to Everywhere, tick PHP under Script location, paste the code into the PHP editor, edit the config and publish. Leave Action/Hook empty. The password form can appear in templates, blocks and page builders, and Everywhere covers them all.

The same code also works unchanged in a small plugin or an mu-plugin.

Customise it

  • Your text: change message. Set it to '' with an empty link_url to remove the paragraph and show only the field.
  • Request link: set link_url, for example home_url( '/request-password/' ) for a page on your site or 'mailto:office@example.com', and change link_text.
  • Other markup, or a different message per post: filter dpc_password_message_html. It gets the HTML and the post.
  • Style it in your theme’s stylesheet, for example:
.dpc-password-message {
	max-width: 40rem;
}

.dpc-password-request {
	font-weight: 600;
}

Gotchas

  • A theme or plugin that builds its own password form without a plain <p> intro is left untouched.
  • The form posts to wp-login.php?action=postpass. If you restrict wp-login.php, keep that action open; Restrict WordPress Admin and Login to Your IP Address does.
  • Password protection hides the content, not the attachments. Uploaded files stay reachable by their URL.

The older version of this post replaced the English sentence with str_replace(), linked to a hard-coded /request-password/ URL with inline styles, and did nothing on translated sites or on WordPress versions with the new wording.

In the Scripts Organizer library Import it with one click from Scripts Organizer.

// newsletter

Three tested WordPress snippets a week

Blocks, security, performance, Tailwind, PHP and React. Copy, paste, ship. You’ll also get DPlugins product updates. No spam, and you can unsubscribe anytime.

// newsletter

Three tested WordPress snippets a week

Blocks, security, performance, Tailwind, PHP and React. Copy, paste, ship. You'll also get DPlugins product updates. No spam, and you can unsubscribe anytime.