Laravel: Accessing PHP from upper view - php

First Laravel Project.
I made a DB::select statement in the upper "master" layer, but when I want to access it from the lower layer I get "variable not defined message.
Master layer:
<!DOCTYPE HTML>
<html class="html">
<head>
<?php $options=DB::select('select * from options'); ?>
<title>#yield('title')</title>
<link href="{{ asset('/css/style.css') }}" rel="stylesheet">
<link href="media/favicon.ico" rel="icon" type="image/x-icon" />
<link href="//netdna.bootstrapcdn.com/bootstrap/3.1.0/css/bootstrap.min.css" rel="stylesheet">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.1.0/js/bootstrap.min.js"></script>
</head>
.
.
.
Other layer:
#extends('layouts.master')
#section('title', 'Inventory')
#section('main')
#parent
<?php
$thumbnails=$options[0]->thumbnails;
?>
.
.
.
Output:
ErrorException in a9ef8ce5f32a327198559f3667e4271b90435dc6.php line 5:
Undefined variable: options (View:
/var/www/html/project/laravel/leltar/resources/views/inventory.blade.php)
What did I wrong?

It looks like you wanted to access $options variable on any given view. You can achieve that by sharing it across all views.
Add the following code to your App\Providers\AppServiceProvider boot() function
View::share('options', DB::select('select * from options'));
Don't forget to import
use Illuminate\Support\Facades\DB;
on the top.

Related

Laravel: Pass variable to Blade Sub Component

There are many questions here that are similar to mine, such as:
Pass variable to a component Laravel 9
Cannot access Blade Component variables inside the view
Passing variable from component into a slot
but I have not found a resolution to my problem in any of them. I've also scoured the doc at: https://laravel.com/docs/9.x/blade#components
I would have thought this would be a simple task.
I have the following structure, in Resources/views:
start.blade.php (uses)
components/layout.blade.php (uses)
components/head.blade.php
From my controller, I call:
$data =
[
'total' => $total,
'uses_form' => true
];
return view('start', $data);
Inside start.blade.php, I have:
<x-layout>
<x-slot name="uses_form">
{{ $uses_form }}
</x-slot>
<!-- additional html -->
</x-layout>
Inside layout.blade.php:
<!DOCTYPE html>
<html lang="en">
<x-head :uses_form:$uses_form />
<!-- also tried: #include('includes.header', ['uses_form' => $uses_form])-->
<body>
<div class="container-fluid">
{{ $slot }}
</div><!--container-fluid-->
</body>
</html>
Finally, in head.blade.php:
<head>
<link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
#if ($uses_form === true)
<link type='text/css' rel='stylesheet' href='/css/form.css' />
#endif
</head>
This results in an:
Undefined variable $uses_form
at:
head.blade.php: line 3
How can I get the variable to be recognized in head.blade.php?
I'm open to other approaches, such as generated the conditional style include, at a higher level, but I rather keep this check in head.blade.php for maintainability.
Using Laravel version 9.48.0
Edit (Additional Notes)
If I var_dump $uses_form from the top of layout.blade.php, I get the following:
object(Illuminate\View\ComponentSlot)#301 (2) {
["attributes"]=> object(Illuminate\View\ComponentAttributeBag)#299 (1) {
["attributes":protected]=> array(0) { }
}
["contents":protected]=> string(1) "1"
}
So, it's already changed form.
You can try to pass the variable $uses_form from the parent component layout.blade.php to the child component head.blade.php using following changes and I hope it will helpful to you.
layout.blade.php look like:
<!DOCTYPE html>
<html lang="en">
<x-head :uses-form="$uses_form"/>
<body>
<div class="container-fluid">
{{ $slot }}
</div><!--container-fluid-->
</body>
</html>
head.blade.php look like:
<head>
<link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
#if ($usesForm === true)
<link type='text/css' rel='stylesheet' href='/css/form.css' />
#endif
</head>
I got it working. There were a few things needing adjusting, but, mainly, I needed to modify the component classes to accept the parameter data.
Another change that was needed, was to pass the data to the layout component, at the top of start.blade.php, like so:
<x-layout :hasForm="$hasForm">
Also, as indicated in another answer and in comments, I needed to place the variable in quotes.
Finally, I'm not sure if this was part of problem, but I changed the uses_form variable from snake_case to camelCase.
The changes, from the question are such:
Controller:
$data =
[
'total' => $total,
'hasForm' => true
];
return view('start', $data);
start.blade.php
<x-layout :hasForm="$hasForm">
<!-- additional html -->
</x-layout>
app/View/Components/Layout.php
class Layout extends Component
{
public $hasForm;
public function __construct($hasForm)
{
$this->hasForm = $hasForm;
}
}
layout.blade.php
<!DOCTYPE html>
<html lang="en">
<x-head :hasForm:"$hasForm" />
<body>
<div class="container-fluid">
{{ $slot }}
</div><!--container-fluid-->
</body>
</html>
app/Views/Components/Head.php
class Head extends Component
{
public $hasForm;
public function __construct($hasForm)
{
$this->hasForm = $hasForm;
}
}
head.blade.php
<head>
<link type='text/css' rel='stylesheet' href='/css/vendor/bootstrap.min.css' />
#if ($hasForm === true)
<link type='text/css' rel='stylesheet' href='/css/form.css' />
#endif
</head>
Hope this may help someone else, down the line.

Failed to load CSS in HTTPS protocol

I created a blog using Laravel, and I am having a weird issue. I pushed my project to Heroku (nepshare.herokuapp.com). When I visit this URL my site loads but with no CSS and I refreshed every time to make it load but failed.
Finally, I changed the https://nepshare.herokuapp.com URL to http://nepshare.herokuapp.com (changed from HTTPS to HTTP) then everything works just fine.css are only loaded in HTTP. How to render all CSS in HTTPS protocol? The following is my main layout code:
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<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>
<!-- Fonts -->
<link rel="dns-prefetch" href="//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>
<body>
#include('inc.navbar')
<div class="container">
#include('inc.messages')
#yield('content')
</div>
<script src="/vendor/unisharp/laravel-ckeditor/ckeditor.js"></script>
<script>
CKEDITOR.replace('article-ckeditor');
</script>
</body>
</html>
In your .env file define new property,
REDIRECT_HTTPS = true
In your app/Providers/AppServiceProvider.php add this,
namespace App\Providers;
use Illuminate\Routing\UrlGenerator;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot(UrlGenerator $url)
{
if(env('REDIRECT_HTTPS')) {
$url->formatScheme('https');
}
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
if(env('REDIRECT_HTTPS')) {
$this->app['request']->server->set('HTTPS', true);
}
}
}
Now you can use,
<script src="{{ asset('js/app.js') }}" defer></script>
Or you can use secure_asset() helper function but secure_asset() method only use https: https://laravel.com/docs/5.1/helpers#method-secure-asset
secure_asset()
The secure_asset function generates a URL for an asset using HTTPS.
$url = secure_asset('img/photo.jpg');

My variable does not seem to be available in blade view

My Route...
Route::get('/test', function () {
$word = ['Hello'];
return view('test', $word);
});
My Blade View...
<!DOCTYPE html>
<html lang="en">
<head>
<title>Laravel Quickstart - Basic</title>
<link href="{{ asset('/css/app.css') }}" rel="stylesheet"/>
<link href="{{ asset('/css/Test.css') }}" rel="stylesheet"/>
<!-- CSS And JavaScript -->
</head>
<body>
<div class="container">
<nav class="navbar navbar-default">
{{$word}}
</nav>
</div>
</body>
</html>
I get the following erro when accessing the app via a browser...
(2/2) ErrorException Undefined variable: word (View:
/home/vagrant/Code/Laravel/resources/views/test.blade.php)
When I remove $word form the blade view and replace with a static string "test" it displays correctly.
no idea why the blade view can't see the $word varible, any ideas anyone?
You need to return it to the view in one of two ways:
return view('test', compact('word'));
Or
return view('test', ['word' => $word]);
Either of these methods will then enable you to use the $word variable from within the blade file
You can see an example of this within the documentation here: https://laravel.com/docs/5.4/blade#displaying-data
Change this line
return view('test', $word);
To
return view('test', compact('word'));
The variable will be available in your blade.
To complete Karl's answer, you can see an example there : https://laravel.com/docs/5.4/views#creating-views

Flash Message Laravel 5.2 using toast materialize

can you help me solve this problem ? so in this case i want to show flash message in the next page after button click & action (save, update, delete) success perform...
i've read this https://www.tutorialspoint.com/materialize/materialize_dialogs.htm and also http://materializecss.com/dialogs.html but idk how to use it in my controller
public function hapuskeluhan($id){
$keluh = keluhan::findOrFail($id);
$keluh->delete();
return redirect('lihatkeluhan');
}
For Example is function delete, how could my toast appear before it redirect ? or maybe after ? please kindly help me brother
Try this
#if(session('message'))
<script>
Materialize.toast("{{ #session('message') }}", 5000);
</script>
#endif
I think you need to pass the message along with the redirection to be displayed on the view.
public function hapuskeluhan($id)
{
$keluh = keluhan::findOrFail($id);
$keluh->delete();
return redirect('lihatkeluhan')->with(['message', 'Record Deleted!']);
}
and in your view you could access the session variable message as
Materialize.toast({{ session('message') }}, duration, 'rounded');
and initiate a click so that the toast is displayed
$(document).ready(function () {
$("your element containing materialize handle").click();
});
The answer of #Mohammad Arshad is correct. Thank you.
Just to clarify things, I put my code bellow to communicate the system login.
If you want to work with colors, for example, on login success (green) or login fail (red). Just populate the third parameter of materialize toast with 'green' or 'red' respectively.
On UserController.php file:
<?php
namespace App\Http\Controllers\Login;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
use Hash;
use App\User;
class UserController extends Controller
{
public function login(Request $request)
{
$data = $request->all();
if(Auth::attempt([ 'email'=>$data['email'], 'password'=>$data['password'] ]))
{
\Session::flash('message', ['msg'=>'Login done successfully!', 'class'=>'green']);
return redirect()->route('user.index');
}
\Session::flash('message', ['msg'=>'Login failed. Check your data.', 'class'=>'red']);
return redirect()->route('user.index');
}
}
On site.blade.php file:
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
<meta charset="iso-8859-1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ config('site.name', 'YourSite') }}</title>
<link rel="stylesheet" type="text/css" href="{{ asset('lib/materialize/dist/css/materialize.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('css/style.css') }}">
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
<header>
#include('yourHeaderCode._site._nav')
</header>
<main>
<!-- Your main code -->
#yield('content')
</main>
#include('yourFooterCode._site._footer')
<!-- Scripts -->
<script src="{{ asset('lib/jquery/dist/jquery.js') }}"></script>
<script src="{{ asset('lib/materialize/dist/js/materialize.js') }}"></script>
#if(Session::has('message'))
<script type="text/javascript">
Materialize.toast("{{ Session::get('message')['msg'] }}", 4000, "{{ Session::get('mensagem')['class'] }}");
</script>
#endif()
</body>
</html>

Passing array from view(Blade) to another view(Blade) in laravel

I have master layout of laravel blade template main.blade.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>#yield('title','My Site')</title>
</head>
<body>
#yield('container','Content area')
{{ HTML::script('assets/js/jquery-1.9.0.js') }}
</body>
</html>
I extended it for another view index.blade.php
#extend('main')
I want to add javascript links to master layout(main.blade.php) if exists in child layout(index.blade.php)
added code in index.blade.php
$extraJs = array('plugins1.js','plugins2.js');
#section('extraJs')
{{ $extraJs }}
#stop
So, How can I add javascript to master layout if exists in child blade?
In php:
<?php
if(isset($extraJs)):
foreach($extraJs as $js):
?>
<script src="assets/js/<?php echo $js ?>" type="text/javascript" />
<?php endforeach; endif; ?>
You can just add a yield in your main.blade.php, like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>#yield('title','My Site')</title>
</head>
<body>
#yield('container','Content area')
{{ HTML::script('assets/js/jquery-1.9.0.js') }}
#yield('javascripts')
</body>
</html>
Then, in your child layout, you add a section for it, like you did. For example:
#section('javascripts')
#foreach($scripts as $script)
{{ HTML::script('ets/js/' . $script) }}
#endforeach
#stop
If you add another child view which doesn't need to use extra javascripts, Laravel won't complain because the section is optional.
I wouldn't really encourage this method but since you asked. It is definitely possible to pass something "up" in the view tree. You can just define a PHP variable in your view and it will be available anywhere in the layout.
index.blade.php
<?php $extraJs = array('plugins1.js','plugins2.js'); ?>
main.blade.php
#if(isset($extraJs))
#foreach($extraJs as $js)
<script src="{{ asset('assets/js/'.$js) }}" type="text/javascript" />
#endforeach
#endif
As you can see I also converted your code in the layout to blade and made use of the asset() function to generate absolute URLs
Note Instead of doing it this way there are other methods. For example View composers or defining the plugins in the controller.

Categories