how to escape curly braces in vue.js - laravel

I have data in my database that may contains curly braces{{ }}.
{{-- inside app.blade.php --}}
<!-- vue app -->
<div id="app">
...code
<div> {{ $data }} </div>
...code
</div>
so if I want to display it to the user this data cause problem if it's inside Vue app. and vue think it's javascript codes to execute.
for example if the $data is equal to {{ title->links() }} then I get an error and the whole app doesn't compile at all. (it passes the blade template).
[Vue warn]: Error compiling template:
invalid expression: expected expression, got '>' in
_s(title->links())
Raw expression: {{ title->links() }}
305| <div>{{ title->links() }}</div>
| ^^^^^^^^^^^^^^^^^^^^^^^
what is the best way to escape {{ }} curly braces for user data (in Vue.js)??

You need use the v-pre or v-html directive:
<div v-pre>{{ data }}</div>
or
<div v-html="'{{ data }}'"></div>
ref link https://v2.vuejs.org/v2/api/#v-pre

Related

AlpineJS inline function and Laravel #json

I have a problem passing a PHP variable to a variable inside an alpine variable or function. Here is a simple example.
#php
$test = "Hello World's testing";
#endphp
<div x-data="{
message: #json($test)
}">
<span x-text="message"></span>
</div>
The problem comes from the fact that x-data is using the double-quote to wrap the encoded data. I know I could "externalize" the x-data, but I really need it to be inline.
I have a basic workaround (using backticks) for example, but I wanted to know if there is a better way to do this.
EDIT
The example is using a string... but the PHP variable can be a boolean or even an array. That's why I'm using #json.
I' d use Template Strings.. Easy to read, no need to escape multiple quotes.
<div>
#php
$test = "Hello World's testing";
#endphp
<div x-data="{
message: `{{ $test }}`
}">
<span x-text="message"></span>
</div>
</div>
Will this not work?:
#php
$test = "Hello World's testing";
#endphp
<div x-data="{
message: {{ json_encode($test) }}
}">
<span x-text="message"></span>
</div>

Laravel Components: default content in {{ slots }}

In old-style Laravel blade templated we used to use #section('section-name') in the following way:
{{-- h1para.blade.php --}}
<h1>
#section('heading')
Heading from Template
#endsection
</h1>
<p>
#yield('details')
</p>
And then extend that template with:
{{-- content.blade.php --}}
#extends('h1para')
#section('details')
Content from content page
#endsection
In the above, my rendered HTML output would look like the following, because the "missing" 'heading' section in the extending file means that we default back to the content in the template:
<h1>Heading from Template</h1>
<p>Content from content page</p>
But in the new components way of doing things, I do:
{{-- .../components/h1para.blade.php --}}
<h1>{{ $heading }}</h1>
<p>{{ $slot }}</p>
In case you haven't gathered, the question is: how do I set a default value for a slot's contents, such that if it isn't supplied in the extending component/template, it falls back to that default?
(I've done my searches, but haven't been able to find the same question asked before)
EDIT:
I should add that I've seen the solution (in the Laravel documentation):
<h1>{{ $heading ?? 'Default Heading Here' }}</h1>
But this seems only to be appropriate if the default value is a short easy to manage string. If the default is a long stream of HTML, then it wouldn't work for my needs.
EDIT 2:
Just to reiterate: the whole point of the question is that the default content could be a long stream of HTML. Solving the problem by passing in a string (be that formatted as HTML or not) wouldn't work for my real-world needs.
I think the solution is this:
{{-- .../component/template.blade.php --}}
<div>
#if (isset($heading))
{{ $heading }}
#else
<h1>Default Heading<span class="subhead">default subheadin and lots of other html content</span></h1>
#endif
<p>{{ $slot }}</p>
</div>
It's not super elegant, but I think it's the only solution. Anyone else have a better answer, I'd love to hear it.
If you pass data like:
<x-h1para header="<span>Header content</span>">
<div>Default slot content here</div>
</x-h1para>
You can display in your component like:
<div>
<h1>{!! $heading ?? 'Default Heading Here' !!}</h1>
{{ $slot }}
</div>

Using v-html in blade foreach loop [Vue warn]: Error compiling template

I'm trying to use vues v-html in a blade foreach loop:
#foreach($entries as $entry)
<h3>{{ $entry->created_at->toRfc822String() }}</h3>
<div v-html="<p>hello world</p>">
</div>
<hr>
#endforeach
When I do that I get this error:
[Vue warn]: Error compiling template:
invalid expression: Unexpected token '<' in
<p>hello world</p>
Raw expression: v-html="hello world"
The reason I want to use v-html is because I intend to use a method to output markdown like <div v-html="marked({{$entry-content}})">
Assuming marked to be a method declared in Vue instance, you can quote the interpolated content but first convert all the characters in it to corresponding HTML entities. For example,
<div v-html="marked('{{ htmlentities($entry->content) }}')">
I suggest to write this in the model as a computed property.
class Entry extends Model {
protected $appends = ['content_html']
getContentHtmlAttribute() {
return htmlentities($this->content);
}
}
Then use the computed field in your template,
<div v-html="marked('{{ $entry->content_html }}')">

Hugo definition of non-site level variables/parameters query

I am using Hugo Universal Theme. I am new to static site generators. This question is for someone who is familiar with hugo templates.
In layouts/partials/features.html we can see where $element.name and $element.name.description are rendered:
{{ if isset .Site.Params "features" }}
{{ if .Site.Params.features.enable }}
{{ if gt (len .Site.Data.features) 0 }}
<section class="bar background-white">
<div class="container">
{{ range $index, $element := sort .Site.Data.features "weight" }}
{{ if eq (mod $index 3) 0 }}
<div class="col-md-12">
<div class="row">
{{ end }}
<div class="col-md-4">
<div class="box-simple">
<div class="icon">
<i class="{{ .icon }}"></i>
</div>
<h3>{{ $element.name }}</h3>
<p>{{ $element.description | markdownify }}</p>
</div>
</div>
{{ if or (eq (mod $index 3) 2) (eq $index (sub (len $.Site.Data.features) 1 )) }}
</div>
</div>
{{ end }}
{{ end }}
</div>
</section>
{{ end }}
{{ end }}
{{ end }}
The data to be rendered in this case are defined in data/features/consulting.yaml as follows:
weight: 4
name: "Consulting"
icon: "fa fa-lightbulb-o"
description: "Fifth abundantly made Give sixth hath..."
What should I do to add new variable to the yaml file that can later then be rendered through the html file when hugo is compiling the site. I tried to simply add another parameter param1 and then insert a corresponding line in the html file as <p>{{ $element.param1 | markdownify }}</p> just below description paragraph but got error
ERROR 2018/08/23 10:42:42 Error while rendering "home" in "":
template: index.html:22:11: executing "index.html" at <partial
"features.ht...>: error calling partial: template:
partials/features.html:18:56: executing "partials/features.html" at
: wrong number of args for markdownify: want 1 got 0
Clearly it seems I have not been able to define the variable properly, but where should I do that? I can add another site variable to config.toml, but I want to learn how to make page specific variables that can be defined in yaml/frontmatter type entries. I tried reading about hugo variables but got bogged down in what is a variable and what is a shortcode. Many thanks for your help with this example.
Well, I found a working answer, but I still do not fully understand how it fits with Hugo variable system, so a better answer and or comments are highly welcome.
It appears quite simple. I had to define url variable in the yaml file:
name: "History"
position: "Hx"
url: "/blog/2018/08/23/01-history/"
and then use in the html file like this:
{{ if .url }}
<a href="{{ .url }}">
<h5>{{ .name }}</h5>
</a>
{{ else }}
<h5>{{ .name }}</h5>
{{ end }}
What it does is puts the .name in link tag, if .url is defined in .yaml. This works also if an absolute URL is given. So it appears that a page variable is referred to as .myVariable. the template authors used $element.name in another place as above, which confused me.
I also can refer to the parameter defined in the frontmatter as .Params.name
I found pointers at https://github.com/devcows/hugo-universal-theme/pull/166 and tested in adjusting the template; it works well.

Parse content from function as were it Blade contents

I've got a blade view in which I load another string via a function called retrieveSomeContent()
retrieveSomeContent() returns a string, which could hold 'references' like {{ $action->url }}. The data itself is available in the view.
// myView.blade.php
// simplified
...
{{-- doesn't work
displays {{ $action->url }}
--}}
{!! retrieveSomeContent('section1B') !!}
{{-- works --}}
{{ $action->url }}
...
Off course the view right now will just displays {{ ... }} as text instead of parsing it to http://......
How would I be able to parse the string generated via retrieveContent()?

Resources