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 best solutions below

2
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
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
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
On

Since Wordpress 4.7.0

Use sanitize_textarea_field instead of sanitize_text_field

0
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.