Jade - convert new lines to <br/> and keep the content encoded
Asked Answered
H

6

10

I am still not that familiar with the Jade template engine. Is there a way to convert the new lines such as \n to br tags and at the same time keep the other content encoded?

For example

.replace(/\n/g,'</br>')

applied over the encoded value should do the work. However I am not sure how to encode the value and get the result. Is there any helper for this?

Haddington answered 26/1, 2013 at 19:38 Comment(0)
L
15

You can use jades escape method and replace the linebreaks in the return value of that like so:

p !{escape(foo).replace(/\n/g, '<br/>')}

I am not aware of any built-in functionality for your use case.


Looks like pug got rid of the escape function, so this is what you would have to use now:

p !{foo.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>')}
Lungi answered 26/1, 2013 at 19:49 Comment(5)
This is what I am talking about! Thanks mate.Haddington
That's not Jade's method. Since template compiles into JS function, you can use any of node and V8 globals inside it.Equilibrant
While it is true that you can use the global methods, this isn't the global escape method. The global escape method would return %3C for each < instead of &lt; like jades escape method does.Lungi
Trying to format pug error messages in my template, .message !{message.replace(/\n/g, '<br/>')} was enough.Crossly
If message contains <, > or & those won't be escaped correctly. Apparently with pug escape is the global method so you would have to manually replace above mentioned characters: .message !{message.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;').replace(/\n/g, '<br/>')}Lungi
R
12

if you don't exactly need <br>, you can simply put your text within <pre> tag. All whitespaces (including new lines) will be displayed as typed.

Or you could set css rule white-space: pre to preserve whitespace preformatting. Check MDN on this.

Rockribbed answered 25/7, 2014 at 12:39 Comment(3)
Use this in conjuction with word-wrap: break-word;Rawalpindi
word-wrap: break-word breaks the words up at arbitrary points if there are no acceptable points. If you just want simple text formatting with words wrapping to the next line, try white-space: pre-wrapPoachy
Best to use white-space: pre-line in this case, I think.Avon
C
9

escape method, even converts simple space (' ') characters to "%20".

MDN says escape is deprecated and it is meant for encoding strings in url, not html content. Another solution,

each line in foo.split(/\n/)
  = line
  br
Circumference answered 29/6, 2014 at 17:9 Comment(1)
This will leave a trailing newline, unfortunately.Avon
M
1

Most answers say you need to do p !{foo.replace(/\n/g)}. However, that is not enough: \n in regex matches the new line character so you will need to escape the \ in \n. You can do that by adding a additional \ to \n.

The final result:

p !{foo.replace(/\\n/g, '<br />')}

NOTE: If you want to escape the other characters too, you can just add:
.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;')

EDIT:
You can use p #{foo.replace...} to correctly escape all characters in html tags. This can be useful if you want to prevent users from inserting <script>...</script> tags in a input field to hack your website.

Multicellular answered 30/8, 2018 at 18:50 Comment(0)
A
1

Consider whether you really want <br> tags.

If you can use CSS instead

It's better to use white-space: pre-line. See the MDN page, where it says

pre-line

Sequences of white space are collapsed. Lines are broken at newline characters, at <br>, and as necessary to fill line boxes.

This is the same as the normal behaviour, except that newline characters turn into line breaks.

This ought to do what you want.

If you want <br> tags

All of the existing answers here which give <br> tags either don't escape the output for HTML (which can be dangerous), reimplement escaping logic, or leave a trailing newline.

This one is based on Palani's answer but does not leave a trailing newline, and also protects against foo being nullish or false.

each line in (foo || '').split('\n').slice(0, -1)
  = line
  br
= (foo || '').split('\n').pop()

I don't love this solution but I think it's preferable to the others, if you want <br> tags.

If you might be putting large strings through it, it might be a good idea to make a temporary variable for the result of the split so it's not done twice.

Avon answered 21/11, 2021 at 9:45 Comment(0)
M
-1

You can do that simple:

p !{someString.replace(/\n/g, '<br/>')}

Note that this method will correctly escape string.

Mertens answered 13/2, 2014 at 14:38 Comment(1)
it isn't escape the someString variable, and now it can render rich html content, for example xss :(Fulvous

© 2022 - 2024 — McMap. All rights reserved.