Use i18n in both vuejs and blade.php - laravel

I would like to use i18n in both blade.php and vuejs views. Is it possible?
I already made the json file for i18n, it looks like this:
export default {
"en": {
"menu": {
"home":"Home",
"example":"Example"
}
}
}
It works with vuejs but I wonder how to use it in laravel... Is this possible?
Otherwise, is there any way to access a cookie in both laravel and vuejs, or do I need to use axios request for storing it and get it in vue? (I would like to store and read use the lang).
Here is a blade.php view where I would like to use i18n
#if (Route::has('register'))
<li class="nav-item">
<a class="nav-link" href="{{ route('register') }}">{{ __('home.example') }}</a>
</li>
#endif
In vue.js files, all I do is
{{ $t('home.example') }}
I use this library: https://github.com/kazupon/vue-i18n
Thank you very much!

I don't think it's easily possible to use vue-i18n in Blade templates.
Blade templates allow you to use an # symbol in front of curly braces ({{ and }}) to indicate that the expression should not be evaluated by Blade. I wanted to suggest you use that to your advantage and use # {{ $t('home.example') }} inside Blade. I think it would have to be inside your Vue mounted element for Vue-i18n to pick it up. However, Vue replaces the mounted element since Vue 2.x so your Blade templates inside your Vue mounted element would probably get lost.
I think your best bet would be to use a generator to copy all of your Laravel translation strings to Vue-i18n. laravel-vue-i18n-generator
looks like a nice package to do this.
Basically you would then store your translation strings in Laravel and would be able to use them in Blade as normal. Every time you update these strings, you would have to run the generator again to have them available in Vue-i18n where you can access them as usual with Vue-i18n.

Related

Using a vue attribute within laravel brackets "{{"

I'm trying to pass a vue slot property within a wordpress function inside of the laravel brackets "{{ }}" to just get an image. Here is what I'm trying to do:
style="background-image: url({{ get_the_post_thumbnail_url(`slotProps.slide.ID`) }})"
Now it's just returning the wrong post thumbnail url. I've read something about using #{{}} to access the vue slot property within your blade template.
So I was trying to do it like:
style="background-image: url({{ get_the_post_thumbnail_url(#{{slotProps.slide.ID}}) }})"
which led into blade thinking there's a missing closing tag. How will I be able to get the correct thumbnail url using vue and blade?
Any help would be appreciated.

Vue links are formatted weirdly

I am new to Vue js, Inertia and Laravel.
But I have gotten stuck and cannot figure out what the problem is even though I try searching google and looking at videos.
I have this code
<div v-for="(seed, index) in seeds" :key="index">
Id {{ seed.id }}
<inertia-link :href="'/fert/' + '{{ seed.id }}'">
Go to seed
</inertia-link>
</div>
And The first {{ seed.id }} outside of the links looks great, it shows the actual id.
However then {{ seed.id }} within the link formats, so the link shows this:
Id 1Go to seed
Why is it formatting inside the link but not outside? and how to I fix it?
Thanks in advance, and yes I am very noob. sorry
You shouldn't use curly braces in attribute's value.
Using :[attribute-name] already tells Vue that you gonna use some JS expressions in value
:href="'/fert/' + seed.id"
You shouldn't use curly braces within the link. A nicer way to concatenate vars with text is to use template literal ES6 with backticks
<inertia-link :href="`/fert/${seed.id}`">Go to seed</inertia-link>

How to enhance an existing Laravel project with VueJS?

I just finished my project using only the Laravel framework. Now I want to add vue.js into my project to render the views without loading them. I went through some tutorials and found that I need to convert my blade files into Vue components to achieve this. But as I know it's a big process as some of the functions won't work in VueJS. And I don't know how to do it. Please, someone, guide me here on how to do that. Thanks in advance.
Rebuild your basic structure into a Vue template:
// MyTemplate.vue
<template>
<div> <!-- keep this single "parent" div in your template -->
<!-- your Blade layout here -->
</div>
</template>
<script>
export default {
props: [ 'data' ]
}
</script>
Add your Vue template as a global component in app.js:
// app.js
import Vue from 'vue';
window.Vue = Vue;
Vue.component('my-template', require('./MyTemplate.vue').default);
const app = new Vue({
el: '#app'
});
Use this new Vue template in your Blade template as below:
<my-template :data="{{ $onePhpVarThatHoldsAllYourData }}"></my-template>
Once inside the Vue template, you will not be able to reach back to your Laravel methods (e.g. #auth) or for additional data without an Ajax request, so make sure you package all the data you need in your Vue template up front. All of the data you send in will be prefixed inside the Vue template with the name of the prop you assign it to, in this case data.
Note, once you get more familiar with Vue you will likely start segregating the individual data values being passed to your template. For that, you will need to specify additional props in the props array in step 1, e.g.
props: ['a', 'b', 'c'],
and then individually pass their values with
<my-template :a="{{ $a }}" :b="{{ $b }}" :c="{{ $c }}"></my-template>
Convert your Blade directives to Vue directives:
Loops (e.g. #foreach) to v-fors:
#foreach ($items as $item)
<li>{{ $item }}</li>
#endforeach
becomes
<li v-for="item in data.items">{{ item }}</li>
Control structures (e.g. #if ($something !== $somethingElse) ... #endif) to v-ifs:
<div v-if="data.something !== data.somethingElse">
...
</div>
In general, as it was already mentioned in comments, there's no short way for converting your application from blades to VueJS components. Anyway, if you consider migrating to VueJS, I'd recommend you to make a full migration instead of partially using Vue components.
The main idea of migration to VueJS is to transfer all logic that you did in blade templates (like foreach's, if's etc) to Vue components and fetch all data using AJAX requests (e.g. with help of axios or nativelly).
In this case, your controllers should return all data needed for page rendering and Vue components will take care of rest rendering logic.
Also, it's a good option to use vue-router to handle rounding and make your application behave as SPA. In this case, you should create one wildcard route in your application that will return only one blade template. Inside of this template you should insert root tag that will initiate VueJS. The rest will be on the VueJS side.
If you are planning to migrate the whole application then start with authentication.
Part #1: https://codebriefly.com/laravel-jwt-authentication-vue-ja-spa-part-1/
Part #2 https://codebriefly.com/laravel-jwt-authentication-vue-js-spa-part-2/
This tutorial helped me in the past to getting started. After that split your code into components.
If you want to learn basics first then you can go with this tutorial I found this useful.
https://www.youtube.com/playlist?list=PL4cUxeGkcC9gQcYgjhBoeQH7wiAyZNrYa
Hope this helps!

Laravel Blade Highlight Change Tags

I am going to use AngularJS along with Laravel, and I wanted to change Laravel tags to [[ ]] (which I think BTW is nicer since [ ] looks more like blade and is sharper :p )
Anyhow, I changed it with
Blade::setContentTags('[[', ']]'); // for variables and all things Blade
Blade::setEscapedContentTags('[[[', ']]]'); // for escaped data
How do I change the "Bracket Highlight" in Sublime now so that it still highlights my new tags??
Not directly answerting your question, but my solution to have Angular and Blade playing nice is very simple, I create a _partial every time I need some Angular and name this partial just '.php' and not '.blade.php', so if I have a form that uses Angular, I have:
{{ Form::open() }}
#include('_partials.posts.forms.create');
{{ Form::close() }}
In this case the included file would be views/_partials/posts/forms/create.php.
About Sublime, download Blade Syntax Highlighter, this file might give you a clue about how to change that for you:
https://github.com/Medalink/laravel-blade/blob/master/laravel-blade.tmLanguage

Changing Laravel Blade Delimiter

I know that you can change the default blade delimiter using
Blade::setEscapedContentTags('[[', ']]');
Blade::setContentTags('[[[', ']]]');
However I don't know where should I put it so that it only affect single blade template as opposed to putting it at app/start/global.php which affect whole application.
If you only want to use different tags for a single view, you can set the tags in the closure or controller action that will generate the view.
Route::get('/', function()
{
Blade::setEscapedContentTags('[[', ']]');
Blade::setContentTags('[[[', ']]]');
return View::make('home');
});
This could be an issue if you want to use the normal tags {{ and }} in an application layout but your custom ones in a nested view - I'm not sure what the best approach there would be.
The solution with Blade::setEscapedContentTags / Blade::setContentTags doesn't work in the latest versions of Laravel (checked at 5.6).
The recommended approach is (https://laravel.com/docs/5.6/blade#blade-and-javascript-frameworks):
Blade & JavaScript Frameworks
Since many JavaScript frameworks also use "curly" braces to indicate a
given expression should be displayed in the browser, you may use the #
symbol to inform the Blade rendering engine an expression should
remain untouched. For example:
Hello, #{{ name }}.
In this example, the #symbol will be removed by
Blade; however, {{ name }} expression will remain untouched by the
Blade engine, allowing it to instead be rendered by your JavaScript
framework.
The #verbatim Directive
If you are displaying JavaScript variables in
a large portion of your template, you may wrap the HTML in the
#verbatim directive so that you do not have to prefix each Blade echo
statement with an # symbol:
#verbatim
<div class="container">
Hello, {{ name }}.
</div>
#endverbatim
Simply use #verbatim directive.wrap your whole code in it and blade will just ignore all the curly braces.

Resources