Wordpress - Removing "Website" Field from the contact info
Revisited and updated answer:
We can't use the user_contactmethods
filter to remove the website wrapper, because this piece is hardcoded in the user-edit.php
file and not part of the filterable user contacts loop, generated by:
wp_get_user_contact_methods( $profileuser )
Hiding it with CSS
The website row element now got it's own .user-url-wrap
class:
<tr class="user-url-wrap">
<th><label for="url"><?php _e('Website') ?></label></th>
<td>
<input type="url" name="url" id="url"
value="<?php echo esc_attr( $profileuser->user_url ) ?>"
class="regular-text code" />
</td>
</tr>
Previously we had to use jQuery, to target the parent row of the #url
field, for removal.
But now we can easily target the website wrapper and hide it with CSS:
function remove_website_row_wpse_94963_css()
{
echo '<style>tr.user-url-wrap{ display: none; }</style>';
}
add_action( 'admin_head-user-edit.php', 'remove_website_row_wpse_94963_css' );
add_action( 'admin_head-profile.php', 'remove_website_row_wpse_94963_css' );
Hiding other fields
There are similar row classes:
tr.user-{field}-wrap
available for the fields:
admin-color,
comment-shortcuts,
admin-bar-front,
user-login,
role,
super-admin,
first-name,
last-name,
nickname,
display-name,
email,
description,
pass1,
pass2,
sessions,
capabilities,
...
including all the fields from the dynamic user contacts methods.
Here we just replace the {field}
part with the corresponding field name.
Screenshots
Before removing the website row:
After removing the website row:
I resolved the problem with ob_ functions and DOMDocument. It's better than jQuery or CSS for protecting the form.
I use this kind of solution every time when I can't access a part of HTML content through a hook.
function remove_extra_field_profile()
{
$current_file_url = preg_replace( "#\?.*#" , "" , basename( $_SERVER['REQUEST_URI'] ) );
if( $current_file_url == "profile.php" )
{
add_action( 'wp_loaded', function(){ ob_start("profile_callback"); } );
add_action( 'shutdown', function(){ ob_end_flush(); } );
}
}
add_action( 'init', 'remove_extra_field_profile' );
function profile_callback( $html )
{
$profile_dom = new DOMDocument;
$profile_dom->loadHTML( $html );
$all_lines = $profile_dom->getElementsByTagname( 'tr' );
$excludes = array(
'user-rich-editing-wrap',
'user-admin-color-wrap',
'user-comment-shortcuts-wrap',
'show-admin-bar user-admin-bar-front-wrap',
'user-url-wrap',
'user-description-wrap'
);
$deletes = array();
foreach ( $all_lines as $line )
{
$tr_calss = $line->getAttribute("class");
if( in_array( $tr_calss, $excludes ) )
{
$deletes[] = $line;
}
}
$deletes[] = $profile_dom->getElementsByTagname( 'h2' )->item(0);
foreach ($deletes as $delete)
{
$delete->parentNode->removeChild( $delete );
}
return $profile_dom->saveHTML();
}
Expanding on @birgire's and justifying @Patricia Walton's answer, if you only add
add_action('admin_head-user-edit.php','remove_website_row_wpse_94963');
it will only be gone from the page where admin is editing a profile. To also make it disappear when a user edits its own profile add also
add_action('admin_head-profile.php','remove_website_row_wpse_94963');
, like this:
function remove_website_row_wpse_94963() {
if(!current_user_can('manage_options')){
// hide only for non-admins
echo "<script>jQuery(document).ready(function(){jQuery('#url').parents('tr').remove();});</script>";
}
}
add_action('admin_head-user-edit.php','remove_website_row_wpse_94963');
add_action('admin_head-profile.php','remove_website_row_wpse_94963');