WordPress - How to sanitize multi-line text from a textarea without losing line breaks?

14.6k views Asked by At

If I sanitize and save some meta text (called 'message') entered by the user like like this...

update_post_meta($post_id, 'message', sanitize_text_field($_POST['message']));

...and then retrieve and attempt to re-display the text like this...

echo '<textarea id="message" name="message">' . esc_textarea( get_post_meta( $post->ID, 'message', true ) ) . '</textarea>';

...all the line breaks get lost.

In accordance with the WordPress codex, the line breaks are being stripped out by the sanitize_text_field() function. So how can I sanitize the text entered by the user without losing their line breaks?

5

There are 5 answers

2
mpatek On BEST ANSWER

A more elegant solution:

update_post_meta(
    $post_id,
    'message',
    implode( "\n", array_map( 'sanitize_textarea_field', explode( "\n", $_POST['message'] ) ) )
);

Use sanitize_text_field if you want to sanitize text field.

1
user2926055 On

If line breaks are the only thing sanitize_text_field is removing that you want to keep, you could just str_replace for "\n" before and after calling sanitize_text_field.

$fake_newline = '--OMGKEEPTHISNEWLINE--'; # or some unique string
$escaped_newlines = str_replace("\n", $fake_newline, $_POST['message']);
$sanitized = sanitize_text_field($escaped_newlines);
update_post_meta($post_id, 'message', str_replace($fake_newline", "\n", $sanitized));

If you want to customize sanitization more, you should probably rely on more fine-grained sanitize_* functions provided by WordPress.

0
Marcus Domingos On

Tried everything, the only way I was able to make this work was like this:

function.php

wp_customize->add_section('section_id', array(
    'title' => __('custom_section', 'theme_name'),
    'priority' => 10,
    'description' => 'Custom section description',
));

$wp_customize->add_setting('custom_field', array(
    'capability' => 'edit_theme_options',
    'sanitize_callback' => 'sanitize_textarea_field',
));

$wp_customize->add_control('custom_field', array(
    'type' => 'textarea',
    'section' => 'custom_section',
    'label' => __('Custom text area with multiline brakes'),
));

Display in front (ex. footer.php)

<?php $custom_field= get_theme_mod('custom_field');
    if ($custom_field) {
        echo nl2br( esc_html( $custom_field) );
} ?>

Must use 'sanitize_callback' => 'sanitize_textarea_field' and nl2br( esc_html()) to work.

3
NME New Media Entertainment On

Since Wordpress 4.7.0

Use sanitize_textarea_field instead of sanitize_text_field

0
piersb On

I've been trying to use this method myself, and find that apostrophes in the textarea are escaped by backslashes on the way in, which then aren't removed by esc_textarea on the way out.

So I've ended up having to use

stripslashes( esc_textarea( $THING ) ) 

to successfully remove them from the textarea when redisplaying.