Laravel 4 View Composer not firing for layout or subview - view

I'm having trouble getting a View Composer to fire based on a subview. Specifcally:
protected $layout = 'layouts.main';
public function index()
{
return $this->layout->content = View::make('pages.dashboard');
}
pages/dashboard.blade.php contains:
#extends('layouts.main')
#section('content')
Hello World
#stop
Inside layouts/main.blade.php contains:
<html>
<body>
#include('layouts.partials.header')
#include('layouts.partials.sidebar')
#include('layouts.partials.content') // Renders {{ $content }}
</body>
</html>
My view controller is:
View::composer('layouts.auth', function($view)
{
die("Hit the sweet spot!");
});
It will work if I use "pages.dashboard", but not "layouts.main" or "layouts.partials.sidebar". Any idea how to hook to those views?

Using the tip at Get location of view passed into laravel view composer for getting a view name, I debugged every view that was called:
View::composer('*', function($view) {
print $view->getName() . "<br>";
});
I found that the proper name to listen for is "layouts.partials.sidebar". Plugged it in and it worked! Guess it was just a typo on my part the first time.

You registered the composer for layouts.auth view
View::composer('layouts.auth', function($view)
{
die("Hit the sweet spot!");
});
So, it'll work only when layouts.auth will be rendered. To hook the composer for layouts.main you should register it for layouts.main using:
View::composer('layouts.main', function($view)
{
die("Hit the sweet spot!");
});
You may also check this article, could be helpful.

Related

How can i send array of data from laravel blade to controller

I have created a form and I used alpine js to add something to the array data, but I don't know how to pass it to the controller as a post method
It is super important that you read the official Laravel documentation, you are not a magician, so you must get this knowledge from somewhere.
You are not sharing a controller code, so I will assume you have this one:
Route::get('/', function () {
return view('greeting', ['name' => 'James']);
});
If you have this on your view, it will render that name:
<html>
<body>
<h1>Hello, {{ $name }}</h1>
</body>
</html>

How to create a new page layout in Laravel/Livewire

This is a complete new application using Laravel 9 and Livewire
By default you have two layouts, guest and app. I want to create a new layout for all my admin things.
So, first I create a component
php artisan make:component AdminLayout
This creates \app\View\Components\AdminLayout.php, it read as:
<?php
namespace App\View\Components;
use Illuminate\View\Component;
class AdminLayout extends Component {
public function render() { return view('layouts.admin'); }
}
As any of the other two AdminLayout.php or GuestLayout.php
So now I write app\resources\views\layouts\admin.blade.php which is a stantandard HTML with the {{ $slot }} blade directive, something as...
<html>
<head>
...
<title>Admin Page</title>
...
#livewireStyles
#vite([...])
</head>
<body>
<main class="...">
{{ $slot }}
</main>
#livewireScripts
</body>
</html>
Then I create the admin routes... The Index class is in \app\Livewire\Admin\Index.php and it is correctly imported
Route::get('', Index::class)->name('home');
The Index.php reads as
class Index extends Component {
public function render() { return view('livewire.admin.index'); }
}
The \app\resources\views\livewire\admin\index.blade.php reads:
<x-admin-layout>
Hello
</x-admin-layout>
So everything seems to be right... now I have two problems that I can't spot/solve. When I load the http:://server.test/admin it should load this page. 1) It doesn't change the title in the page for Admin Page, 2) It always loads the #livewire('navigation-menu'), and looks like the followin picture:
If I add things above the {{ $slot }} or below, they are rendered. If I add another #livewire('navigation-menu') it is rendered. But I'm not able to take it out, even when I'm not telling to display it.
Any idea?
I just noticed that if I add a comment in the guest layout or the admin layout, it simply ignores it. If I add a comment in the app layout it somehow "propagates" to both the guest and admin layout. Is this the expected behaivour?

Laravel Blade Template - Put php built-function or maybe laravel helper inside yield

do you ever use PHP built-in function inside blade yield ?
For example can we do something like this :
// master layouts
#yield(ucwords('title'))
// view
#section('title', $title)
Note: $title is from controller
I've already try the first example, but it doesn't work. It doesn't output the $title on my view. Right now I am using this in all of my views
// master layouts
#yield('title')
// view 1
#section('title', ucwords($title))
// view 2
#section('title', ucwords($title))
// view 3
#section('title', ucwords($title))
But I think on second example, I'm not DRY my code because I always repeating the ucwords() on each my view. Can we using it on master layout right on yield declaration?
Thank you guys, have a nice work!
You can make your own blade directive for example if you want to make a #ucfirst() then do something like this in AppServiceProvider .
Blade::directive('ucfirst', function ($expression) {
return ucfirst($expression);
});
Past this into boot()
or on each section() you can extend the main layout #section('title', ucwords($title)) or make the helpers like i mentioned above
as you mentioned above you can use yield()
#yield('title',ucwords(strtolower('Your title')))

Nav-tabs don't work on route profile/{name} Laravel

I made a profile page in Laravel with something like /profile/{name} and I use a UserController#showProfile:
public function showProfile($name)
{
if(!Cache::has($name))
{
if(DB::table('users')->where('name', $name)->exists())
{
$user = DB::table('users')->where('name', $name)->get();
Cache::put($name, $user, 10);
}
else
{
return view ('error404');
}
}
return view ('user.profile', ['profile_stats' => Cache::get($name)]);
}
But nav-tabs don't work if I put /profile/{name}, if I let it just /profile in routes everything works.
This is profile.blade.php with nav-tabs: https://pastebin.com/wzKM8wRd and this https://pastebin.com/XLBKX6Gr is the layout.
Route::get('profile/{name}', 'UserController#showProfile');
can you show us content view script: user.profile.blade.php ?
and don't use cache until you make sure that everything works fine.
public function showProfile($name)
{
$user = DB::table('users')->where('name', $name)->get();
return view ('user.profile', ['profile_stats' => $user]);
}
upd
any js errors in the browser console?
navigation works when url ends with /profile/ ? maybe you should try /profile/{name}/
So fix up js errors... and then come back :) looks like your problem with hash navigation isn't laravel issue.
I solved, problem was:
<script type="text/javascript">
window.jQuery || document.write("<script src='js/jquery.js'>"+"<"+"/script>");
</script>
I forgot to put / in front of js/jquery.js:
<script type="text/javascript">
window.jQuery || document.write("<script src='/js/jquery.js'>"+"<"+"/script>");
</script>
However thanks for your answers!

Laravel Sub-menu Within View

Hi I am very new to Laravel and MVC frameworks in general and am looking to create a list of links (in a view within a template) that links to some content. I am using this to display a list of nine people and to display their profile description when the link is clicked on. I have created a model of what the page looks like at http://i.imgur.com/8XhI2Ba.png. The portion that I am concerned with is in blue. Is there a way to route these links to something like /about/link2 or /about?link2 while maintaining the same exact page structure but modifying the ‘link content’ section (on the right of the link menu) to show the specific link's content? I would greatly appreciate it if someone could point me in the right direction, as I have literally no clue where to go with this!
There are a couple ways you can go about doing this.
Templates
Create your route.
Im assuming a lot about your app here but hopefully you get the picture. If you need help with anything in particular, be sure to update your question with the code youve tried so it will be easier to help you.
Route::get('about/{page}', function($page)
{
$profile = Profile::where('name', $page)->first();
return View::make('about')->with('profile', $profile);
});
Modify Template.blade.php
Put this line where you wish for About.blade.php to appear.
#yield('content')
Create your view which will extend your template
#extends('Template')
#section('content')
<h2>User Profile</h2>
<ul>
<li>Name: {{ $profile->name }}</li>
<li>Last Updated: {{ $profile->updated_at }}</li>
</ul>
#stop
AJAX
This solution will utilize AJAX to grab the data from the server and output it on the page.
Route for initial page view
Route::get('about', function($page)
{
$profiles = Profile::all();
return View::make('about')->with('profiles', $profiles);
});
Feel free to follow the same templating structure as before but this time we need to add some javascript into the template to handle the AJAX. Will also need to id everything which needs to be dynamically set so we can easily set it with jquery.
#extends('Template')
#section('content')
<h2>Links</h2>
#foreach($profiles as $profile)
{{ $profile->name }}
#endforeach
<h2>User Profile</h2>
<ul>
<li>Name: <span id="profile_name">{{ $profile->name }}</span></li>
<li>Last Updated: <span id="profile_updated_at">{{ $profile->updated_at }}</span></li>
</ul>
<script>
function setProfile(a)
{
$.ajax({
method: 'get',
url: 'getProfile',
dataType: 'json',
data: {
profile: $(a).data('id')
},
success: function(profile) {
$('#profile_name').html(profile.name);
$('#profile_updated_at').html(profile.updated_at);
},
error: function() {
alert('Error loading data.');
}
});
}
</script>
#stop
Route to handle the AJAX request
Route::get('getProfile', function()
{
$profile_id = Input::get('profile');
$profile = Profile::find($profile_id);
return $profile->toJson();
});
Now, the page should not have to reload and only the profile information should be updated.
Making some assumptions here as no code posted and assuming you're using the latest version of Laravel, Laravel 5.
Lets say you have a table in your database named users and you have a Model named Users (Laravel 5 comes with the Users model as default, see app/Users.php). The users will be the base of our data for the links.
Firstly, you want to register a route so you can access the page to view some information. You can do this in the routes file. The routes file can be found here: app/Http/routes.php.
To register a route add the following code:
Route::get('users', ['uses' => 'UserController#index']);
Now what this route does is whenever we hit the URL http://your-app-name/public/users (URL might be different depending on how you have your app set up, i.e. you may not have to include public) in our web browser it will respond by running the index method on the UserController.
To respond to that route you can set up your UserController as so:
<?php namespace App\Http\Controllers;
class UserController extends Controller {
public function index()
{
}
}
Controllers should be stored in app/Http/Controllers/.
Now lets flesh out the index method:
public function index()
{
// grab our users
$users = App\Users::all();
// return a view with the users data
return view('users.index')->with('users');
}
This grabs the users from the database and loads up a view passing the users data.
Here's what your view could look like:
<!DOCTYPE html>
<html>
<head>
<title>Users Page</title>
</head>
<body>
#foreach($users as $user)
<a href="{{ URL::route('user', ['id' => $user->id]) }}">
{{ $user->username }}
</a>
#endforeach
</body>
</html>
The view code will loop through each user from the $users data we passed to the view and create a link to their user page which is different for each user based on their id (their unique identifier in the DB)
Due to the way I've named it, this would be found in app/views/users/index.blade.php - if you save files ending in blade.php you can use Laravel's templating language, blade.
Now you need to finally set up another route to respond to a user page, for example http://your-app-name/public/user/22.
Route::get('user/{id}', ['uses' => 'UserController#show']);
Then add the show method to UserController
public function show($id)
{
// this will dump out the user information
return \App\User::find($id);
}
Hope that helps a little! Wrote most of it off the top of my head so let me know if you get any errors via comment.
This question is very bare, and it is difficult to actually help your situation without you showing any code. Just to point you in the right direction though, here is what you would need.
A Model called People, this is how you will access your data.
A controller. In this controller you will do the following
Get the ID of the profile you want from the functions parameters
Find that persons information e.g. People::find($person_id);
return the profile view with that persons data e.g. return view('profile')->with('person', $person);
In your view you can then use that data on that page e.g. {{ $person->name }}
For the page that needs to display the links to the people you would have a method in your controller which..
Get all the people data e.g. People::all();
Return a view with that data return view('all-people')->with('people', $people);
You will then need a route to access an individual person. The route will need to pass the persons ID into a controller method e.g.
Route::get('get-person/{id}',
[ 'as' => 'get-person',
'uses' => 'PeopleController#getPerson' ]);
You can then use this route in your view to get the links to each person
#foreach($people as $person)
{{$person->name}}
#endforeach
This would produce the list of links you want.

Resources