Laravel 8 and TailwindCSS Undefined variable: header - laravel

I am new to Laravel 8 and TailwindCSS so I need your help with the following problem.
I just created a new folder inside resources and one blade file that extends the layouts.app. When I access this file through the browser I am getting the following error: Undefined variable: header (View: C:\xampp\htdocs\library\resources\views\layouts\app.blade.php) (View: C:\xampp\htdocs\library\resources\views\layouts\app.blade.php).
On the other hand, if I comment out the variable $header (and $slot) then I don't get the code that I wrote in that blade file.
My code for routes:
`Route::get('/', function () {
return view('welcome');
});
Route::post('books', [BooksController::class, 'store']);
Route::patch('books/{book}', [BooksController::class, 'update']);
Route::delete('books/{book}', [BooksController::class, 'destroy']);
Route::get('/authors/create', [AuthorsController::class, 'create']);
Route::post('authors', [AuthorsController::class, 'store']);
Route::post('/checkout/{book}', [CheckoutBookController::class, 'store']);
Route::post('/checkin/{book}', [CheckinBookController::class, 'store']);
Route::middleware(['auth:sanctum', 'verified'])->get('/dashboard', function () {
return view('dashboard');
})->name('dashboard');`
The code for app.blade:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Fonts -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Nunito:wght#400;600;700&display=swap">
<!-- Styles -->
<link rel="stylesheet" href="{{ asset('css/app.css') }}">
#livewireStyles
<!-- Scripts -->
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.6.0/dist/alpine.js" defer></script>
</head>
<body class="font-sans antialiased">
<div class="min-h-screen bg-gray-100">
#livewire('navigation-dropdown')
<!-- Page Heading -->
<header class="bg-white shadow">
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
{{ $header }}
</div>
</header>
<!-- Page Content -->
<main>
{{ $slot }}
</main>
</div>
#stack('modals')
#livewireScripts
</body>
</html>
And finally, the code for the new blade file called create:
#extends('layouts.app')
#section('content')
<div class="bg-gray-300 h-screen">
<h1>ada</h1>
</div>
#endsection
Thank you in advance,

It seems you're using livewire in your code. Therefore, you need to create a livewire component. You can find a guide on how to do that here: https://laravel-livewire.com/docs/2.x/making-components.
If you go through the guide above, you'll end up with two new files: a livewire component file and a blade view file that renders the component. You can then add the following to the blade file:
<x-slot name="header">
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
{{ __('Page Header') }}
</h2>
</x-slot>
<div class="bg-gray-300 h-screen">
<h1>ada</h1>
</div>
The first part occupies the header's slot while the other takes the main slot. I hope this helps to clarify things a bit.

Related

How to implement alpine component accessible on all pages of the app?

in my Laravel 8 / apline 2.8 / tailwindcss 2 app
I want to make alpine component which must be accessible on all pages of the site and I
want to use footer for this
My resources/views/layouts/app.blade.php has structure :
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
...
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
...
</head>
<body class="flex flex-col min-h-screen">
<header class="h-14 bg-red">
#include('layouts.header')
</header>
<main class="flex-1">
#yield('content')
#yield('scripts')
</main>
<footer class="h-8 bg-green">
#include('layouts.footer')
</footer>
</body>
</html>
But Trying to implement footer comnponent in resources/views/layouts/footer.blade.php :
<div class="m-0 p-0">
<div class="flex w-full p-0 m-0 content-center justify-between md:w-1/2 md:justify-end" x-data="adminFooterComponent()">
...
</div>
</div>
#section('scripts')
<script>
function adminFooterComponent() {
console.log('adminFooterComponent::')
return {
addDonationOpen: false,
}
} // function adminFooterComponent() {
</script>
#endsection
I got error :
Uncaught ReferenceError: adminFooterComponent is not defined
I suppose that I got this error as I did not wrap(as I do on all my pages) my footer in
#section('content')
...
#endsection
section. But I really do not need it, as resources/views/layouts/footer.blade.php is a partial file.
How can I implement alpine component accessible on all pages of the app?
Thanks!
I think the issue arises since the section is included in the footer. To resolve the issue, we can include the section in the actual view or we can just include it in the layout file itself.
Method 1 - In the blade file
#extends('layouts.app')
#section('content')
......
#endsection
#section('scripts')
<script>
function adminFooterComponent() {
console.log('adminFooterComponent::')
return {
addDonationOpen: false,
}
}
</script>
#endsection
Method 2 - In layout file (directly) app.blade.php
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine#v2.8.0/dist/alpine.min.js" defer></script>
</head>
<body class="flex flex-col min-h-screen">
<main class="flex-1">
#yield('content')
</main>
<footer class="h-8 bg-green">
#include('layouts.footer')
</footer>
<script>
function adminFooterComponent() {
console.log('adminFooterComponent::')
return {
addDonationOpen: false,
}
}
</script>
</body>
The straightforward solution is Method 2 so that the code is not replicated.

Laravel vue with two different layout

I that possible to have different layout in laravel vue components?
If we use blades all we need is to change #extends('layouts.app') to #extends('layouts.custom') and then you have different design, but how it's working in vuejs?
Code
This is my App.vue file which is in charge of rendering template of all pages
<template>
<div>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
//navbar
</nav>
<el-container>
<el-header>Header</el-header>
<el-container>
<el-aside width="200px">
<h5>{{site_name}}</h5>
</el-aside>
<el-main>
<a class="sr-only sr-only-focusable" href="#content">Skip to main content</a>
<div>
<transition name="fade">\
//router which renders all components in this part
<router-view id="content" :key="$route.fullPath"></router-view>
</transition>
</div>
</el-main>
</el-container>
<el-footer>Footer</el-footer>
</el-container>
</div>
</template>
and here is my layout blade file:
<!doctype html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="csrf-token" content="{{ csrf_token() }}" />
<title>{{ config('app.name', 'Laravel') }}</title>
<link href="{{ asset('css/app.css') }}" rel="stylesheet" />
</head>
<body>
<div id="app"></div>
<script src="{{ asset('js/app.js') }}"></script>
<script>
window.default_locale = "{{ config('app.locale') }}";
window.fallback_locale = "{{ config('app.fallback_locale') }}";
</script>
</body>
</html>
Basically that aside part in app.vue i only need to show in admin part not front-end (for users)
Any idea?
Pass it as a prop to your component
Something like:
Blade File:
#php
$isLoggedIn = Auth::check();
#endphp
<my-component :is-logged-in="{{ $isLoggedIn }}" </<my-component>

Include inside section doesn't work Laravel Blade

I have a #section inside my child template and I am trying to include another template inside of it, but It doesn't work.
My parent template looks like this:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- X-csrf token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
{{-- Custom CSS --}}
#yield('head')
{{-- Open Sans font --}}
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300&display=swap" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{$title}}</title>
</head>
<body>
#yield('content')
#yield('footer')
</body>
{{-- JS files --}}
#yield('javascript')
</html>
My child template code:
#extends('layouts.app')
{{-- /////////////////////////////////////////////////////////////////// --}}
#section('head')
{{-- Custom CSS for index page --}}
<link rel="stylesheet" type="text/css" href="{{asset('css/index.css')}}">
#endsection
{{-- /////////////////////////////////////////////////////////////////// --}}
#section('header')
<header>
#include('navbar')
</header>
#endsection
{{-- /////////////////////////////////////////////////////////////////// --}}
#section('content')
<section>
<div class="entry-texts">
<h1 class="entry-title">Welcome to my page!</h1>
<h2 class="entry-subtitle">Must be some text in here.</h2>
</div>
</section>
#endsection
{{-- /////////////////////////////////////////////////////////////////// --}}
#section('footer')
<footer>
</footer>
#endsection
{{-- /////////////////////////////////////////////////////////////////// --}}
#section('javascript')
#endsection
The problem is in this part:
#section('header')
<header>
#include('navbar')
</header>
#endsection
It does not include my navbar in the header tag. My navbar file is located in views directory. What is the problem and what am I doing wrong here?
Your parent template does not have #yield('header') and your navbar is in a section called #section('header')
You are yielding head but using section header. This is the problem.
Use #section('head')
just a little clarification. your head section should end with stop as in for yielding scripts and styles:
#section('head')
{{-- Custom CSS for index page --}}
<link rel="stylesheet" type="text/css" href="{{asset('css/index.css')}}">
#stop
You should try this:
<!DOCTYPE html>
<html lang="en">
<head>
<!-- X-csrf token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
{{-- Custom CSS --}}
#section('head')
{{-- Open Sans font --}}
<link href="https://fonts.googleapis.com/css?family=Open+Sans:300&display=swap" rel="stylesheet">
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>{{$title}}</title>
</head>
<body>
#yield('content')
#yield('footer')
</body>
{{-- JS files --}}
#yield('javascript')
</html>

Vue JS simple v-model functionality on input field not working in Laravel app

I am using vuejs as a drop in for some minor functionality in a Laravel app (i.e. not components) and for some reason that I'm yet to discover v-model is not working.
Here's my base layout blade file that was generated via php artisan make:auth, contents mostly removed as irrelevant:
resources/views/layouts/app.blade.php
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<!-- css imports etc. -->
</head>
<body>
<div id="app">
<nav class="navbar navbar-expand-md navbar-light navbar-laravel">
<!-- nav menu -->
</nav>
<main class="py-4">
#yield('content')
</main>
</div>
#stack('scripts') <---- Javascript goes here!
</body>
</html>
Here's the file where v-model is being used and not working, again, irrelevant parts have been removed:
resources/views/instructors/create.blade.php
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-body">
<div class="card-title">
<h2>vue: #{{ message }}</h2> <-- This works
<div>
<input type="text" v-model="message"> <-- Blank!!?
</div>
</div>
<!-- more html -->
</div>
</div>
</div>
</div>
</div>
#endsection
#push('scripts')
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
</script>
#endpush
The input field which v-model="message" is bound to is completely empty, however, when outputting message via curly braces I can see it's value. This is what it looks like:
Any ideas what's going wrong? I have checked the console and Vue dev tools and no errors show up, in fact nothing shows up at all in Vue dev tools - an issue perhaps? I copy pasted these code snippets from the Vue docs introduction to make sure I wasn't doing something silly. I have tried setting the data attribute inside the Vue instance as a function returning an object but it makes no difference. I also have the code working here: https://jsfiddle.net/eywraw8t/249625/ where the input field shows the value of message as I am expecting it to work.
I wouldn't consider myself a Vue pro but I'm no beginner and I cannot quite figure out what's going on. Any help would be appreciated, thanks!
Update
Thanks to everyone who answered. Made a silly mistake... I forgot that there is some JS that is pulled in, in the <head> when running make:auth - this includes Vue by default. I forgot to look properly here as assumed it would be prior to </body>. I believe the two JS scrips were conflicting which was causing the issue. See head below:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- CSRF Token -->
<meta name="csrf-token" content="{{ csrf_token() }}">
<title>{{ config('app.name', 'Laravel') }}</title>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script> <-- Vue included here
<!-- Fonts -->
<link rel="dns-prefetch" href="https://fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
I commented the script out and it's working fine now.
For vue.js 2 use the following:
<html>
<body>
<div id="app">
<h1>Vue: #{{message}}</h1>
<input v-model="message">
</div>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script type="text/javascript">
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
}
});
</script>
</body>
</html>
For more details how to work on v-model: Laracasts_episodes_2
try the following code
#extends('layouts.app')
#section('content')
<div class="container">
<div class="row justify-content-center">
<div class="col-md-8">
<div class="card">
<div class="card-body">
<div class="card-title">
<div id="app">
<template>
<div>
<div class="card-title">
<h2>
Add Instructor
</h2>
<h2>vue: #{{ message }}</h2>
<div>
<input type="text" v-model="message">
</div>
</div>
</div>
</template>
</div>
</div>
<!-- more html -->
</div>
</div>
</div>
</div>
</div>
#endsection
#push('script')
<script>
var app = new Vue({
el: '#app',
data: {
message: 'Hello Vue!'
},
});
</script>
#endpush

[Vue warn]: Cannot find element: #app

I have a fresh installed laravel project with all the components updated.
All I did is tried to add app.js in my welcome.blade.php file, after adding the following I get this error
[Vue warn]: Cannot find element: #app
I followed this thread, but it's not relevant as my script is at the bottom of the page.
https://laracasts.com/discuss/channels/vue/fresh-laravel-setup-and-vue-2-wont-work
Here's my file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{$project}} | {{ $title }}</title>
<!-- Fonts -->
<link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">
<!-- Styles -->
<link href="/css/app.css" rel="stylesheet" type="text/css"/>
<style>
...
</style>
</head>
<body class="sticky-nav">
<div id="nav">
<div class="display-sm">
<header class="top-header">
<span class="menu-icon">☰</span>
</header>
</div>
<div class="custom-container">
<div id="logo" class="float-left">
<img alt="xyz" src="/images/xyz.png"/><span> xyz</span>
</div>
<div id="btn-project" class="float-right">
<a title="project" href="#" class="btn btn-project">Project</a>
</div>
</div>
</div>
<div class="sub-container">
<h1 id="header-title">{{ $header_title }}</h1>
<h2 id="meta-data"><i class="fa fa"></i>{{$location}} <span id="category"> <i></i>{{$category}} </span></h2>
<div class="clear"></div>
</div>
<script src="/js/app.js"></script>
<script>
var wrap = $(".sticky-nav");
wrap.on("scroll", function (e) {
if (this.scrollTop > 147) {
wrap.find('#nav').addClass("fix-nav");
} else {
wrap.find('#nav').removeClass("fix-nav");
}
});
</script>
</body>
</html>
Error says it all. Vue can't find #app element, so you need to add it:
<div id='app'></div>
https://v2.vuejs.org/v2/guide/
Sometime everything seems got , but we are still getting same error then you have to copy this code and paste in app. blade.
<head>
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<div id="app">
.
.
.
.
.
.
</div>
</body>
Verify that your main design file app.blade.php contains a div with the app id just after the <body> tag just like this:
<body>
<div id="app">
.
.
.
</div>
</body>

Resources