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

5

21

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?

Nichellenichol answered 7/12, 2013 at 17:3 Comment(0)
S
34

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.

Syphilis answered 6/8, 2014 at 18:36 Comment(2)
Thank you - this is not only elegant, but brilliant.Thrower
I would not change the user input but rather just insert a post meta with using $wpdb->query() directly, which would avoid a WordPress's boredom of meta input sanitization, which you don't need for your particular case.Exarch
P
54

Since Wordpress 4.7.0

Use sanitize_textarea_field instead of sanitize_text_field

Punkah answered 7/5, 2017 at 23:4 Comment(3)
Thanks for this. It's a shame there's no way to change the top answer - esp. as it could take years for this answer to get more upvotes that the selected top answer.Nichellenichol
This is the one you all are looking for. Should replace the other answers.Isle
This is the true solution.Overelaborate
S
34

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.

Syphilis answered 6/8, 2014 at 18:36 Comment(2)
Thank you - this is not only elegant, but brilliant.Thrower
I would not change the user input but rather just insert a post meta with using $wpdb->query() directly, which would avoid a WordPress's boredom of meta input sanitization, which you don't need for your particular case.Exarch
S
1

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.

Shiff answered 7/12, 2013 at 17:14 Comment(1)
Thanks for this. A couple of errors in your code, but I get the idea. Here's the working code: $NEW_LINE = "\n"; $NEW_LINE_SUBSTITUTE = "NEWLINE-SUBSTITUTE"; update_post_meta($post_id, 'message', sanitize_text_field( str_replace($NEW_LINE, $NEW_LINE_SUBSTITUTE, $_POST['message'] )) ); echo '<textarea id="message" name="message">' . str_replace($NEW_LINE_SUBSTITUTE, $NEW_LINE, esc_textarea( get_post_meta( $post->ID, 'message', true ) ) ) . '</textarea>';Nichellenichol
P
0

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.

Pitapat answered 7/1, 2016 at 11:51 Comment(0)
C
0

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.

Caroleecarolin answered 4/8, 2021 at 22:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.