Thyrosis's avatar

New lines removed by blade (Vue)

Hi all!

First off, this question is probably related more to Vue than Laravel, but seeing as it's come to me via the Laravel course, I'll post it here.

I've been following the 'Create a forum' series and am running into an issue here which hasn't been covered (yet? I'm at episode 36). And due to the way Jeffrey walks us through it, it hasn't come up either. If it will (or has and I missed it), feel free to point me to the episode.

The thing is, creating threads and replies works fine. Displaying it too, just as long as you write everything in one paragraph.

As soon as you use the enter-button to create new lines, you run into a problem. Because it is saved correctly (you can check in the database but you'll also see the new lines when editing a reply), but in display mode it will skip all the returns and render everything on the same line.

In straight up Laravel/Blade I would do something like this.

<div>
    {{ nl2br($reply->body) }}
</div>

But, seeing as the reply is passed to the Vue Reply-component, I'm at a loss.

<reply :attributes="{{ $reply }}" inline-template v-cloak>
    <div v-if="editing">
        <div class="form-group">
            <textarea class="form-control" v-model="body" ></textarea>
        </div>

        <button class="btn btn-success btn-sm" @click="update">Update</button>
        <button class="btn btn-warning btn-sm" @click="editing = false">Cancel</button>
    </div>

    <div v-else v-text="body">
        
    </div>
</reply>

And then there is no $reply->body to parse through nl2br.

So, what am I missing? How to I get Vue to display the body with the new lines preserved?

Many thanks in advance!

0 likes
3 replies
Thyrosis's avatar

Right, since posting this question, I've tried to create a prototype function nl2br based on php.js' rendition:

bootstrap.js

window.Vue.prototype.nl2br = function (body) {
    return (body + '').replace(/([^>\r\n]?)(\r\n|\n\r|\r|\n)/g, '$1' + '<br />' + '$2');
}

reply.vue

data() {
            return {
                editing: false,
                body: this.nl2br(this.data.body),
                id: this.data.id
            }
        },

Now, this kinda works. I mean, I now see that I do have new lines. The only issue is, it's now sent as literal output to the browser...

23:19<br /> <br /> Still wondering about new lines though...<br /> <br /> This should be on one!<br /> <br /> /edit: but it isn't.

And the Vue-reply data.body looks like this:

body:"23:19<br />\n<br />\nStill wondering about new lines though...<br />\n<br />\nThis should be on one!<br />\n<br />\n/edit: but it isn't."

So now I have a body with HTML-linebreaks, but they're not parsed as HTML so they don't break.

Any ideas?

MaverickChan's avatar
Level 47
{!! nl2br($anythingRaw) !!}

in Vue


<div v-html="anything"></div>
Thyrosis's avatar

v-html instead of v-text... it's that simple!

Thanks @MaverickChan!

For anyone following the course too, I've changed the logic in Reply.vue like this:

<!-- <button class="btn btn-default btn-sm" @click="editing = true">Edit</button> -->
<button class="btn btn-default btn-sm" @click="setEditing">Edit</button>

<!-- at the data method, use the nl2br prototype function (see previous post) -->
        data() {
            return {
                editing: false,
                body: this.nl2br(this.data.body),
                id: this.data.id
            }
        },

<!-- add another method called setEditing to make sure you only see the raw body when editing, not the nl2brd one. -->
        methods: {
            setEditing() {
                this.editing = true;
                this.body = this.data.body;
            },

Please or to participate in this conversation.